Reputation: 23
I'm very confused as to what is wrong here. I am getting an undefined reference error to an array I have defined the same way as two others which are not throwing errors elsewhere in the code.
undefined reference to `shift7seg::numbers'
shift7seg.cpp code showing other function using similarly defined arrays being used
uint8_t shift7seg::convert_char(const char& OGchar){
uint8_t converted;
switch (OGchar){
case 'A':
converted = capital[0];
break;
case 'h':
converted = lower[3];
break;
//more cases removed for posting
}
return converted;
}
uint8_t shift7seg::convert_num(const uint8_t& OGnum){
uint8_t converted;
if(OGnum<10){
converted = numbers[OGnum];
}
else{
converted = blank;
}
return converted;
}
shift7seg.h showing definitions of arrays being used
class shift7seg{
public:
//constructor, choose pins to use as well as display size
shift7seg(const uint8_t _dataPin,
const uint8_t _latchPin,
const uint8_t _clkPin,
const uint8_t _num_digits);
static constexpr uint8_t numbers[10] = // 7 segment values for decimals 0..9
{
//TRUTH TABLE | 0 = segment on
//ABCDEFGH | 1 = segment off
B00000011, //0 | A
B10011111, //1 | -----
B00100101, //2 | F | | B
B00001101, //3 | | G |
B10011001, //4 | -----
B01001001, //5 | E | | C
B01000001, //6 | | |
B00011111, //7 | -----
B00000001, //8 | D
B00011001 //9 |
};
static constexpr uint8_t capital[13] =
{
B00010001, //A or R, 0
B00000001, //B 1
B01100011, //C 2
B00000011, //D or O, 3
B01100001, //E 4
B01110001, //F 5
B01000001, //G 6
B10010001, //H 7
B10000111, //J 8
B11100011, //L 9
B00110001, //P 10
B01001001, //S 11
B10000011 //U or V, 12
};
static constexpr uint8_t lower[9] =
{
B11000001, //b 0
B11100101, //c 1
B10000101, //d 2
B11010001, //h 3
B10011111, //l 4
B11010101, //n 5
B11000101, //o 6
B11110101, //r 7
B11000111 //u or v, 8
};
Dialect is C++11 I cannot for the life of me figure out what I have done wrong. Talking to the rubber duck has done nothing so far.
More of the error code is here.
more undefined references to `shift7seg::numbers' follow
collect2.exe: error: ld returned 1 exit status
exit status 1
Upvotes: 2
Views: 1955
Reputation: 36882
Somewhere in your code you are ODR-using numbers
but you don't have a definition for it.
Here's a simple version of your problem (wandbox):
#include <iostream>
#include <cstdint>
class shift7seg {
public:
static constexpr std::uint8_t numbers[10] = {};
};
int main() {
// taking the address is ODR-use
std::cout << &shift7seg::numbers[0] << '\n';
}
Possible solutions are
compile with -std=c++17
(or later) where all static constexpr
data members are implicitly inline
and don't need out-of-line definitions
Add an out-of-line definition in your implementation file (shift7seg.cpp) like this (wandbox):
constexpr std::uint8_t shift7seg::numbers[10];
Upvotes: 3
Reputation: 11047
First of all, I think the prefix is 0B
in those binary literals, not B
. Second of all, you need c++17 to compile it because of the static constexpr stuff.
quote
If a static data member is declared constexpr, it is implicitly inline and does not need to be redeclared at namespace scope. This redeclaration without an initializer (formerly required as shown above) is still permitted, but is deprecated.
from https://en.cppreference.com/w/cpp/language/static
Upvotes: 0