Home > Software design >  "Does not name a type" compile error, right after the definition of the class template in
"Does not name a type" compile error, right after the definition of the class template in

Time:09-27

I have compiled this code in Eclipse IDE with GCC and with having C standard / dialect equal to C 11 without any error.

template<typename TYPE>
class ToSerialHex
{
public:
  enum
  {
    DIGITS_COUNT = uint8_t(sizeof(TYPE)) * uint8_t(2)
  };

  uint8_t digits[DIGITS_COUNT];

  ToSerialHex(TYPE value)
  {
    for(size_t idx = 0; idx < sizeof(TYPE);   idx) {
      uint8_t temp = byteOf(value, sizeof(TYPE) - idx - 1U);
      digits[idx * 2] = temp / 16U;
      digits[(idx * 2)  1] = temp % 16U;
    }
  }
};

template<typename PRINTER_OBJECT_TYPE, typename VALUE_TYPE>
size_t operator<<(PRINTER_OBJECT_TYPE& printerObject, const ToSerialHex<VALUE_TYPE> &hexObject)
{
  typedef ToSerialHex<VALUE_TYPE> HEX_TYPE;
  size_t count = 0;
  for(size_t idx = 0; idx < HEX_TYPE::DIGITS_COUNT;   idx) {
    count  = printerObject.print(hexObject.digits[idx], HEX);
  }
  return count;
}

But when I compile it in Arduino IDE / envrionment which has the same C dialect, I get this error:

error: 'ToSerialHex' does not name a type

The whole program for Arduino is:

#include <Wire.h>

#include <ctype.h> 

constexpr uint32_t serialSpeed = 115200;

constexpr uint8_t EEPROM_sector = 83;
constexpr uint8_t System_sector = 87;

constexpr uint16_t maxbytesPerLine = 16;

constexpr uint16_t EEPROMbytes = 2048;
constexpr uint16_t I2Cpasswordbytes = 4;
constexpr uint16_t RF0passwordbytes = 4;
constexpr uint16_t RF1passwordbytes = 4;
constexpr uint16_t RF2passwordbytes = 4;
constexpr uint16_t DSFIDbytes = 1;
constexpr uint16_t AFIbytes = 1;
constexpr uint16_t UIDbytes = 8;
constexpr uint16_t Configurationbytes = 1;
constexpr uint16_t Lockbitbytes = 2;
constexpr uint16_t SSSbytes = 10;

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(serialSpeed);  // start serial for output
}




//**********************************************************
typedef decltype(sizeof(1)) size_t;

template<typename TYPE>
uint8_t byteOf(TYPE value, size_t idx)
{
  value <<= ((sizeof(TYPE) - idx - size_t(1)) * 8);
  value >>= ((sizeof(TYPE) - size_t(1)) * 8);
  return uint8_t(value);
}

template<typename TYPE>
class ToSerialHex;

template<typename TYPE>
class ToSerialHex
{
public:
  enum
  {
    DIGITS_COUNT = uint8_t(sizeof(TYPE)) * uint8_t(2)
  };

  uint8_t digits[DIGITS_COUNT];

  ToSerialHex(TYPE value)
  {
    for(size_t idx = 0; idx < sizeof(TYPE);   idx) {
      uint8_t temp = byteOf(value, sizeof(TYPE) - idx - 1U);
      digits[idx * 2] = temp / 16U;
      digits[(idx * 2)  1] = temp % 16U;
    }
  }
};
template<typename PRINTER_OBJECT_TYPE, typename VALUE_TYPE>
size_t operator<<(PRINTER_OBJECT_TYPE& printerObject, const ToSerialHex<VALUE_TYPE> &hexObject)
{
  typedef ToSerialHex<VALUE_TYPE> HEX_TYPE;
  size_t count = 0;
  for(size_t idx = 0; idx < HEX_TYPE::DIGITS_COUNT;   idx) {
    count  = printerObject.print(hexObject.digits[idx], HEX);
  }
  return count;
}



template<uint16_t NORMAL_BLOCK_COUNT, uint16_t SPECIAL_COUNT>
struct Window{
  enum : uint16_t {
    normal_block_count = NORMAL_BLOCK_COUNT,
    special_count = SPECIAL_COUNT,
  };
};


namespace helpers {
template<uint8_t DEVICE_ADDRESS, uint16_t MAX_SPECIAL_BLOCKS_PER_LINE, uint16_t NORMAL_PER_LINE, char NORMAL_BLOCK_HEADER, char SPECIAL_BLOCK_HEADER, char NORMAL_BLOCK_FOOTER, char SPECIAL_BLOCK_FOOTER, uint16_t MAX_SPECIAL_PER_LINE, uint16_t NORMAL_BLOCK_COUNT, uint16_t SPECIAL_COUNT, uint16_t ... OTHERS>
class Windows
{
  typedef Windows<DEVICE_ADDRESS, MAX_SPECIAL_BLOCKS_PER_LINE, NORMAL_PER_LINE, NORMAL_BLOCK_HEADER, SPECIAL_BLOCK_HEADER, NORMAL_BLOCK_FOOTER, SPECIAL_BLOCK_FOOTER, MAX_SPECIAL_PER_LINE, OTHERS ...> next;
public:
  static void go() {
    if(NORMAL_BLOCK_COUNT) {
      if(isprint(NORMAL_BLOCK_HEADER)) {
        for (uint16_t idx = 0; idx < 4 *NORMAL_PER_LINE;   idx) {
          Serial.print(NORMAL_BLOCK_HEADER);
        }
        Serial.println("");
      }

      for(uint16_t lineCounter = NORMAL_BLOCK_COUNT; lineCounter--;) {
        Wire.requestFrom(int(DEVICE_ADDRESS), int(NORMAL_PER_LINE), int(true));
  
        char read[NORMAL_PER_LINE] = {};
        {
          uint8_t idx = 0;
          while (Wire.available()) {
            read[idx  ] = Wire.read();
          }
        }
  
        for (uint16_t idx = 0; idx < NORMAL_PER_LINE;   idx) {
          Serial << ToSerialHex<uint8_t>(read[idx]);
          Serial.print(", ");
        }
  
        for (uint16_t idx = 0; idx < NORMAL_PER_LINE;   idx) {
          if (isalnum(read[idx])) {
            Serial.print(read[idx]);
          } else {
            Serial.print(".");
          }
        }
  
        Serial.println("");
        delay(10);
      }

      if(isprint(NORMAL_BLOCK_FOOTER)) {
        for (uint16_t idx = 0; idx < 4 *NORMAL_PER_LINE;   idx) {
          Serial.print(NORMAL_BLOCK_FOOTER);
        }
        Serial.println("");
      }
    }

    if (SPECIAL_COUNT) {
      if(isprint(SPECIAL_BLOCK_HEADER)) {
        for (uint16_t idx = 0; idx < 4 * MAX_SPECIAL_PER_LINE;   idx) {
          Serial.print(SPECIAL_BLOCK_HEADER);
        }
        Serial.println("");
      }

      for(uint16_t lineCounter = SPECIAL_COUNT / MAX_SPECIAL_PER_LINE; lineCounter--;) {
        Wire.requestFrom(int(DEVICE_ADDRESS), int(MAX_SPECIAL_PER_LINE), int(true));

        char read[MAX_SPECIAL_PER_LINE] = {};
        {
          uint8_t idx = 0;
          while (Wire.available()) {
            read[idx  ] = Wire.read();
          }
        }

        for (uint16_t idx = 0; idx < MAX_SPECIAL_PER_LINE;   idx) {
          Serial << ToSerialHex<uint8_t>(read[idx]);
          Serial.print(", ");
        }

        for (uint16_t idx = 0; idx < MAX_SPECIAL_PER_LINE;   idx) {
          if (isalnum(read[idx])) {
            Serial.print(read[idx]);
          } else {
            Serial.print(".");
          }
        }

        Serial.println("");
        delay(10);
      }

      if(SPECIAL_COUNT % MAX_SPECIAL_PER_LINE) {
        Wire.requestFrom(int(DEVICE_ADDRESS), int(SPECIAL_COUNT % MAX_SPECIAL_PER_LINE), int(true));

        char read[SPECIAL_COUNT % MAX_SPECIAL_PER_LINE] = {};
        {
          uint8_t idx = 0;
          while (Wire.available()) {
            read[idx  ] = Wire.read();
          }
        }

        for (uint16_t idx = 0; idx < SPECIAL_COUNT % MAX_SPECIAL_PER_LINE;   idx) {
          Serial << ToSerialHex<uint8_t>(read[idx]);
          Serial.print(", ");
        }

        for (uint16_t idx = 0; idx < SPECIAL_COUNT % MAX_SPECIAL_PER_LINE;   idx) {
          if (isalnum(read[idx])) {
            Serial.print(read[idx]);
          } else {
            Serial.print(".");
          }
        }

        Serial.println("");
        delay(10);
      }

      if(isprint(SPECIAL_BLOCK_FOOTER)) {
        for (uint16_t idx = 0; idx < 4 * MAX_SPECIAL_PER_LINE;   idx) {
          Serial.print(SPECIAL_BLOCK_FOOTER);
        }
        Serial.println("");
      }
    }
    return next::go();
  }

public:
  Windows(uint16_t offset = 0) {
    Wire.beginTransmission(DEVICE_ADDRESS);
    Wire.write(offset / 256);
    Wire.write(offset % 256);
    Wire.endTransmission();
    go();
  }
};

template<uint8_t DEVICE_ADDRESS, uint16_t MAX_SPECIAL_BLOCKS_PER_LINE, uint16_t NORMAL_PER_LINE, char NORMAL_BLOCK_HEADER, char SPECIAL_BLOCK_HEADER, char NORMAL_BLOCK_FOOTER, char SPECIAL_BLOCK_FOOTER, uint16_t MAX_SPECIAL_PER_LINE, uint16_t NORMAL_BLOCK_COUNT, uint16_t SPECIAL_COUNT>
class Windows<DEVICE_ADDRESS, MAX_SPECIAL_BLOCKS_PER_LINE, NORMAL_PER_LINE, NORMAL_BLOCK_HEADER, SPECIAL_BLOCK_HEADER, NORMAL_BLOCK_FOOTER, SPECIAL_BLOCK_FOOTER, MAX_SPECIAL_PER_LINE, NORMAL_BLOCK_COUNT, SPECIAL_COUNT>
{
public:
  static void go() {
    if(NORMAL_BLOCK_COUNT) {
      if(isprint(NORMAL_BLOCK_HEADER)) {
        for (uint16_t idx = 0; idx < 4 *NORMAL_PER_LINE;   idx) {
          Serial.print(NORMAL_BLOCK_HEADER);
        }
        Serial.println("");
      }

      if(isprint(NORMAL_BLOCK_FOOTER)) {
        for (uint16_t idx = 0; idx < 4 *NORMAL_PER_LINE;   idx) {
          Serial.print(NORMAL_BLOCK_FOOTER);
        }
        Serial.println("");
      }
    }
    for(uint16_t lineCounter = NORMAL_BLOCK_COUNT; lineCounter--;) {
      Wire.requestFrom(int(DEVICE_ADDRESS), int(NORMAL_PER_LINE), int(true));

      char read[NORMAL_PER_LINE] = {};
      {
        uint8_t idx = 0;
        while (Wire.available()) {
          read[idx  ] = Wire.read();
        }
      }

      for (uint16_t idx = 0; idx < NORMAL_PER_LINE;   idx) {
        Serial << ToSerialHex<uint8_t>(read[idx]);
        Serial.print(", ");
      }

      for (uint16_t idx = 0; idx < NORMAL_PER_LINE;   idx) {
        if (isalnum(read[idx])) {
          Serial.print(read[idx]);
        } else {
          Serial.print(".");
        }
      }

      Serial.println("");
      delay(10);
    }

    if (SPECIAL_COUNT) {
      if(isprint(SPECIAL_BLOCK_HEADER)) {
        for (uint16_t idx = 0; idx < 4 * MAX_SPECIAL_PER_LINE;   idx) {
          Serial.print(SPECIAL_BLOCK_HEADER);
        }
        Serial.println("");
      }

      for(uint16_t lineCounter = SPECIAL_COUNT / MAX_SPECIAL_PER_LINE; lineCounter--;) {
        Wire.requestFrom(int(DEVICE_ADDRESS), int(MAX_SPECIAL_PER_LINE), int(true));

        char read[MAX_SPECIAL_PER_LINE] = {};
        {
          uint8_t idx = 0;
          while (Wire.available()) {
            read[idx  ] = Wire.read();
          }
        }

        for (uint16_t idx = 0; idx < MAX_SPECIAL_PER_LINE;   idx) {
          Serial << ToSerialHex<uint8_t>(read[idx]);
          Serial.print(", ");
        }

        for (uint16_t idx = 0; idx < MAX_SPECIAL_PER_LINE;   idx) {
          if (isalnum(read[idx])) {
            Serial.print(read[idx]);
          } else {
            Serial.print(".");
          }
        }

        Serial.println("");
        delay(10);
      }

      if(SPECIAL_COUNT % MAX_SPECIAL_PER_LINE) {
        Wire.requestFrom(int(DEVICE_ADDRESS), int(SPECIAL_COUNT % MAX_SPECIAL_PER_LINE), int(true));

        char read[SPECIAL_COUNT % MAX_SPECIAL_PER_LINE] = {};
        {
          uint8_t idx = 0;
          while (Wire.available()) {
            read[idx  ] = Wire.read();
          }
        }

        for (uint16_t idx = 0; idx < SPECIAL_COUNT % MAX_SPECIAL_PER_LINE;   idx) {
          Serial << ToSerialHex<uint8_t>(read[idx]);
          Serial.print(", ");
        }

        for (uint16_t idx = 0; idx < SPECIAL_COUNT % MAX_SPECIAL_PER_LINE;   idx) {
          if (isalnum(read[idx])) {
            Serial.print(read[idx]);
          } else {
            Serial.print(".");
          }
        }

        Serial.println("");
        delay(10);
      }

      if(isprint(SPECIAL_BLOCK_FOOTER)) {
        for (uint16_t idx = 0; idx < 4 * MAX_SPECIAL_PER_LINE;   idx) {
          Serial.print(SPECIAL_BLOCK_FOOTER);
        }
        Serial.println("");
      }
    }
  }

public:
  Windows(uint16_t offset = 0) {
    Wire.beginTransmission(DEVICE_ADDRESS);
    Wire.write(offset / 256);
    Wire.write(offset % 256);
    Wire.endTransmission();
    go();
  }
};

} // namespace helpers

template<uint8_t DEVICE_ADDRESS, uint16_t MAX_SPECIAL_BLOCKS_PER_LINE = 3, uint16_t NORMAL_PER_LINE = 5, char NORMAL_BLOCK_HEADER = '[', char SPECIAL_BLOCK_HEADER = '(', char NORMAL_BLOCK_FOOTER = ']', char SPECIAL_BLOCK_FOOTER = ')'>
struct Dump {
  template<uint16_t ... values>
  class Windows:
      public helpers::Windows<DEVICE_ADDRESS, MAX_SPECIAL_BLOCKS_PER_LINE, NORMAL_PER_LINE, NORMAL_BLOCK_HEADER , SPECIAL_BLOCK_HEADER, NORMAL_BLOCK_FOOTER, SPECIAL_BLOCK_FOOTER, MAX_SPECIAL_BLOCKS_PER_LINE * NORMAL_PER_LINE, values ...>
      {};
};
//*********************************************************

bool done = false;

typedef Dump<EEPROM_sector> Dump_type;
typedef Dump_type::Windows<0, 1,   8, 40,   34, 899,   25, 262,   25,0,   0, 1,   0, 131   ,51,0> Windows_type;

void loop() {
  if(not done) {
    Serial.println("");
    Serial.println("");
    Serial.println("");
    Serial.println("");
    Serial.println("");

    Windows_type();
        
    done = true;
  }

  delay(2000);
}

The error happens right after the end of the definition(end of the ToSerialHex class scope).

The whole error is:

I2C_eeprom_read_3:77:120: error: 'ToSerialHex' does not name a type
   77 | };
      |                                                                                                                        ^          
I2C_eeprom_read_3:77:131: error: expected ',' or '...' before '<' token
   77 | };
      |                                                                                                                                   ^
exit status 1
'ToSerialHex' does not name a type

And in order to mimic Arduino environment I used this program in eclipse:

#include <iostream>

#include "ctype.h"

class serial{
public:
    serial(...){}
    int print(...){return 0;}
    int println(...){return 0;}
} Serial;

static constexpr int HEX = 0;

class wire{
public:
    wire(...){}
    void beginTransmission(...){}
    void endTransmission(...){}
    void write(...){}
    int read(...){return 0;}
    void requestFrom(...){}
    bool available(...){ return true;}
} Wire;

void delay(...){}

typedef decltype(sizeof(1)) size_t;

template<typename TYPE>
uint8_t byteOf(TYPE value, size_t idx)
{
    value <<= ((sizeof(TYPE) - idx - size_t(1)) * 8);
    value >>= ((sizeof(TYPE) - size_t(1)) * 8);
    return uint8_t(value);
}

template<typename TYPE>
class ToSerialHex
{
public:
    enum : size_t
    {
        DIGITS_COUNT = uint8_t(sizeof(TYPE)) * uint8_t(2)
    };

    uint8_t digits[DIGITS_COUNT];

    ToSerialHex(TYPE value)
    {
        for(size_t idx = 0; idx < sizeof(TYPE);   idx) {
            uint8_t temp = byteOf(value, sizeof(TYPE) - idx - 1U);
            digits[idx * 2] = temp / 16U;
            digits[(idx * 2)  1] = temp % 16U;
        }
    }
};

template<typename PRINTER_OBJECT_TYPE, typename VALUE_TYPE>
size_t operator<<(PRINTER_OBJECT_TYPE& printerObject, const ToSerialHex<VALUE_TYPE> &hexObject)
{
    typedef ToSerialHex<VALUE_TYPE> HEX_TYPE;
    size_t count = 0;
    for(size_t idx = 0; idx < HEX_TYPE::DIGITS_COUNT;   idx) {
        count  = printerObject.print(hexObject.digits[idx], HEX);
    }
    return count;
}



template<uint16_t NORMAL_BLOCK_COUNT, uint16_t SPECIAL_COUNT>
struct Window{
    enum : uint16_t {
        normal_block_count = NORMAL_BLOCK_COUNT,
        special_count = SPECIAL_COUNT,
    };
};


namespace helpers {
template<uint8_t DEVICE_ADDRESS, uint16_t MAX_SPECIAL_BLOCKS_PER_LINE, uint16_t NORMAL_PER_LINE, char NORMAL_BLOCK_HEADER, char SPECIAL_BLOCK_HEADER, char NORMAL_BLOCK_FOOTER, char SPECIAL_BLOCK_FOOTER, uint16_t MAX_SPECIAL_PER_LINE, uint16_t NORMAL_BLOCK_COUNT, uint16_t SPECIAL_COUNT, uint16_t ... OTHERS>
class Windows
{
    typedef Windows<DEVICE_ADDRESS, MAX_SPECIAL_BLOCKS_PER_LINE, NORMAL_PER_LINE, NORMAL_BLOCK_HEADER, SPECIAL_BLOCK_HEADER, NORMAL_BLOCK_FOOTER, SPECIAL_BLOCK_FOOTER, MAX_SPECIAL_PER_LINE, OTHERS ...> next;
public:
    static void go() {
        if(NORMAL_BLOCK_COUNT) {
            if(isprint(NORMAL_BLOCK_HEADER)) {
                for (uint16_t idx = 0; idx < 4 *NORMAL_PER_LINE;   idx) {
                    Serial.print(NORMAL_BLOCK_HEADER);
                }
                Serial.println("");
            }

            if(isprint(NORMAL_BLOCK_FOOTER)) {
                for (uint16_t idx = 0; idx < 4 *NORMAL_PER_LINE;   idx) {
                    Serial.print(NORMAL_BLOCK_FOOTER);
                }
                Serial.println("");
            }
        }
        for(uint16_t lineCounter = NORMAL_BLOCK_COUNT; lineCounter--;) {
            Wire.requestFrom(DEVICE_ADDRESS, NORMAL_PER_LINE, true);

            char read[NORMAL_PER_LINE] = {};
            {
                uint8_t idx = 0;
                while (Wire.available()) {
                    read[idx  ] = Wire.read();
                }
            }

            for (uint16_t idx = 0; idx < NORMAL_PER_LINE;   idx) {
                Serial << ToSerialHex<uint8_t>(read[idx]);
                Serial.print(", ");
            }

            for (uint16_t idx = 0; idx < NORMAL_PER_LINE;   idx) {
                if (isalnum(read[idx])) {
                    Serial.print(read[idx]);
                } else {
                    Serial.print(".");
                }
            }

            Serial.println("");
            delay(10);
        }

        if (SPECIAL_COUNT) {
            if(isprint(SPECIAL_BLOCK_HEADER)) {
                for (uint16_t idx = 0; idx < 4 * MAX_SPECIAL_PER_LINE;   idx) {
                    Serial.print(SPECIAL_BLOCK_HEADER);
                }
                Serial.println("");
            }

            for(uint16_t lineCounter = SPECIAL_COUNT / MAX_SPECIAL_PER_LINE; lineCounter--;) {
                Wire.requestFrom(DEVICE_ADDRESS, MAX_SPECIAL_PER_LINE, true);

                char read[MAX_SPECIAL_PER_LINE] = {};
                {
                    uint8_t idx = 0;
                    while (Wire.available()) {
                        read[idx  ] = Wire.read();
                    }
                }

                for (uint16_t idx = 0; idx < MAX_SPECIAL_PER_LINE;   idx) {
                    Serial << ToSerialHex<uint8_t>(read[idx]);
                    Serial.print(", ");
                }

                for (uint16_t idx = 0; idx < MAX_SPECIAL_PER_LINE;   idx) {
                    if (isalnum(read[idx])) {
                        Serial.print(read[idx]);
                    } else {
                        Serial.print(".");
                    }
                }

                Serial.println("");
                delay(10);
            }

            if(SPECIAL_COUNT % MAX_SPECIAL_PER_LINE) {
                Wire.requestFrom(DEVICE_ADDRESS, SPECIAL_COUNT % MAX_SPECIAL_PER_LINE, true);

                char read[SPECIAL_COUNT % MAX_SPECIAL_PER_LINE] = {};
                {
                    uint8_t idx = 0;
                    while (Wire.available()) {
                        read[idx  ] = Wire.read();
                    }
                }

                for (uint16_t idx = 0; idx < SPECIAL_COUNT % MAX_SPECIAL_PER_LINE;   idx) {
                    Serial << ToSerialHex<uint8_t>(read[idx]);
                    Serial.print(", ");
                }

                for (uint16_t idx = 0; idx < SPECIAL_COUNT % MAX_SPECIAL_PER_LINE;   idx) {
                    if (isalnum(read[idx])) {
                        Serial.print(read[idx]);
                    } else {
                        Serial.print(".");
                    }
                }

                Serial.println("");
                delay(10);
            }

            if(isprint(SPECIAL_BLOCK_FOOTER)) {
                for (uint16_t idx = 0; idx < 4 * MAX_SPECIAL_PER_LINE;   idx) {
                    Serial.print(SPECIAL_BLOCK_FOOTER);
                }
                Serial.println("");
            }
        }
        return next::go();
    }

public:
    Windows(uint16_t offset = 0) {
        Wire.beginTransmission(DEVICE_ADDRESS);
        Wire.write(offset / 256);
        Wire.write(offset % 256);
        Wire.endTransmission();
        go();
    }
};

template<uint8_t DEVICE_ADDRESS, uint16_t MAX_SPECIAL_BLOCKS_PER_LINE, uint16_t NORMAL_PER_LINE, char NORMAL_BLOCK_HEADER, char SPECIAL_BLOCK_HEADER, char NORMAL_BLOCK_FOOTER, char SPECIAL_BLOCK_FOOTER, uint16_t MAX_SPECIAL_PER_LINE, uint16_t NORMAL_BLOCK_COUNT, uint16_t SPECIAL_COUNT>
class Windows<DEVICE_ADDRESS, MAX_SPECIAL_BLOCKS_PER_LINE, NORMAL_PER_LINE, NORMAL_BLOCK_HEADER, SPECIAL_BLOCK_HEADER, NORMAL_BLOCK_FOOTER, SPECIAL_BLOCK_FOOTER, MAX_SPECIAL_PER_LINE, NORMAL_BLOCK_COUNT, SPECIAL_COUNT>
{
public:
    static void go() {
        if(NORMAL_BLOCK_COUNT) {
            if(isprint(NORMAL_BLOCK_HEADER)) {
                for (uint16_t idx = 0; idx < 4 *NORMAL_PER_LINE;   idx) {
                    Serial.print(NORMAL_BLOCK_HEADER);
                }
                Serial.println("");
            }

            if(isprint(NORMAL_BLOCK_FOOTER)) {
                for (uint16_t idx = 0; idx < 4 *NORMAL_PER_LINE;   idx) {
                    Serial.print(NORMAL_BLOCK_FOOTER);
                }
                Serial.println("");
            }
        }
        for(uint16_t lineCounter = NORMAL_BLOCK_COUNT; lineCounter--;) {
            Wire.requestFrom(DEVICE_ADDRESS, NORMAL_PER_LINE, true);

            char read[NORMAL_PER_LINE] = {};
            {
                uint8_t idx = 0;
                while (Wire.available()) {
                    read[idx  ] = Wire.read();
                }
            }

            for (uint16_t idx = 0; idx < NORMAL_PER_LINE;   idx) {
                Serial << ToSerialHex<uint8_t>(read[idx]);
                Serial.print(", ");
            }

            for (uint16_t idx = 0; idx < NORMAL_PER_LINE;   idx) {
                if (isalnum(read[idx])) {
                    Serial.print(read[idx]);
                } else {
                    Serial.print(".");
                }
            }

            Serial.println("");
            delay(10);
        }

        if (SPECIAL_COUNT) {
            if(isprint(SPECIAL_BLOCK_HEADER)) {
                for (uint16_t idx = 0; idx < 4 * MAX_SPECIAL_PER_LINE;   idx) {
                    Serial.print(SPECIAL_BLOCK_HEADER);
                }
                Serial.println("");
            }

            for(uint16_t lineCounter = SPECIAL_COUNT / MAX_SPECIAL_PER_LINE; lineCounter--;) {
                Wire.requestFrom(DEVICE_ADDRESS, MAX_SPECIAL_PER_LINE, true);

                char read[MAX_SPECIAL_PER_LINE] = {};
                {
                    uint8_t idx = 0;
                    while (Wire.available()) {
                        read[idx  ] = Wire.read();
                    }
                }

                for (uint16_t idx = 0; idx < MAX_SPECIAL_PER_LINE;   idx) {
                    Serial << ToSerialHex<uint8_t>(read[idx]);
                    Serial.print(", ");
                }

                for (uint16_t idx = 0; idx < MAX_SPECIAL_PER_LINE;   idx) {
                    if (isalnum(read[idx])) {
                        Serial.print(read[idx]);
                    } else {
                        Serial.print(".");
                    }
                }

                Serial.println("");
                delay(10);
            }

            if(SPECIAL_COUNT % MAX_SPECIAL_PER_LINE) {
                Wire.requestFrom(DEVICE_ADDRESS, SPECIAL_COUNT % MAX_SPECIAL_PER_LINE, true);

                char read[SPECIAL_COUNT % MAX_SPECIAL_PER_LINE] = {};
                {
                    uint8_t idx = 0;
                    while (Wire.available()) {
                        read[idx  ] = Wire.read();
                    }
                }

                for (uint16_t idx = 0; idx < SPECIAL_COUNT % MAX_SPECIAL_PER_LINE;   idx) {
                    Serial << ToSerialHex<uint8_t>(read[idx]);
                    Serial.print(", ");
                }

                for (uint16_t idx = 0; idx < SPECIAL_COUNT % MAX_SPECIAL_PER_LINE;   idx) {
                    if (isalnum(read[idx])) {
                        Serial.print(read[idx]);
                    } else {
                        Serial.print(".");
                    }
                }

                Serial.println("");
                delay(10);
            }

            if(isprint(SPECIAL_BLOCK_FOOTER)) {
                for (uint16_t idx = 0; idx < 4 * MAX_SPECIAL_PER_LINE;   idx) {
                    Serial.print(SPECIAL_BLOCK_FOOTER);
                }
                Serial.println("");
            }
        }
    }

public:
    Windows(uint16_t offset = 0) {
        Wire.beginTransmission(DEVICE_ADDRESS);
        Wire.write(offset / 256);
        Wire.write(offset % 256);
        Wire.endTransmission();
        go();
    }
};

} // namespace helpers

template<uint8_t DEVICE_ADDRESS, uint16_t MAX_SPECIAL_BLOCKS_PER_LINE = 3, uint16_t NORMAL_PER_LINE = 5, char NORMAL_BLOCK_HEADER = '[', char SPECIAL_BLOCK_HEADER = '(', char NORMAL_BLOCK_FOOTER = ']', char SPECIAL_BLOCK_FOOTER = ')'>
struct Dump {
    template<uint16_t ... values>
    class Windows:
            public helpers::Windows<DEVICE_ADDRESS, MAX_SPECIAL_BLOCKS_PER_LINE, NORMAL_PER_LINE, NORMAL_BLOCK_HEADER , SPECIAL_BLOCK_HEADER, NORMAL_BLOCK_FOOTER, SPECIAL_BLOCK_FOOTER, MAX_SPECIAL_BLOCKS_PER_LINE * NORMAL_PER_LINE, values ...>
            {};
};


constexpr uint8_t EEPROM_sector = 83;
typedef Dump<EEPROM_sector> Dump_type;
typedef Dump_type::Windows<0, 1,   8, 40,   34, 899,   25, 262,   25,0,   0, 1,   0, 131   ,51,0> Windows_type;





int main() {
    Windows_type();
    std::cout << "THE END" << std::endl;
    return 0;
}

CodePudding user response:

It's exactly the "piece of art" preprocessing in the Arduino (as mentioned by @user17732522) , that causes those errors. This is how it looks like after preprocessing (relevant lines only):

#include <Arduino.h>
#line 1 "C:\\Users\\kiiv\\AppData\\Local\\Temp\\arduino_modified_sketch_530601\\sketch_sep24a.ino"
#include <Wire.h>

#include <ctype.h> 

constexpr uint32_t serialSpeed = 115200;

constexpr uint8_t EEPROM_sector = 83;
constexpr uint8_t System_sector = 87;

constexpr uint16_t maxbytesPerLine = 16;

constexpr uint16_t EEPROMbytes = 2048;
constexpr uint16_t I2Cpasswordbytes = 4;
constexpr uint16_t RF0passwordbytes = 4;
constexpr uint16_t RF1passwordbytes = 4;
constexpr uint16_t RF2passwordbytes = 4;
constexpr uint16_t DSFIDbytes = 1;
constexpr uint16_t AFIbytes = 1;
constexpr uint16_t UIDbytes = 8;
constexpr uint16_t Configurationbytes = 1;
constexpr uint16_t Lockbitbytes = 2;
constexpr uint16_t SSSbytes = 10;

#line 24 "C:\\Users\\kiiv\\AppData\\Local\\Temp\\arduino_modified_sketch_530601\\sketch_sep24a.ino"
void setup();
#line 34 "C:\\Users\\kiiv\\AppData\\Local\\Temp\\arduino_modified_sketch_530601\\sketch_sep24a.ino"
template<typename TYPE>uint8_t byteOf(TYPE value, size_t idx);
#line 65 "C:\\Users\\kiiv\\AppData\\Local\\Temp\\arduino_modified_sketch_530601\\sketch_sep24a.ino"
template<typename PRINTER_OBJECT_TYPE, typename VALUE_TYPE>size_t operator<<(PRINTER_OBJECT_TYPE& printerObject, const ToSerialHex<VALUE_TYPE> &hexObject);
#line 24 "C:\\Users\\kiiv\\AppData\\Local\\Temp\\arduino_modified_sketch_530601\\sketch_sep24a.ino"
void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(serialSpeed);  // start serial for output
}

Now you can see why it reports error on line 65 (full code reported it on 65 instead of yours 67) and also why you can compile it on anything that doesn't do crappy preprocessing for the beginners, that can't handle forward declarations for functions :)

BTW: if you move: template<typename TYPE> class ToSerialHex; to the line 22, it'll work again

BTW2: the Arduino IDE allows to add another files into the "sketch" directory, so you can just remove everything from the .ino file and create .cpp file with everything in it (including setup and loop) - it just needs #include <Arduino.h> if you don't have it already. Like this you'll completely avoid this .ino prepreprocessor and therefore all magicall bugs it causes

  • Related