Below error occurs while I was writing two functions xxxx as part of uni work. The IDE I'm using is Visual Studio Code.
The problem was that when I tried to compile a single file in the folder code/myIO, it threw an error:
(I've replaced the folder's path with ($). I promise the problem wasn't there)
cd ($) && clang r.cpp -o ($)/r -D LOCAL -Wall -O2 -fsanitize=undefined
Undefined symbols for architecture arm64:
"_Tp::INT", referenced from:
split(char const*, _Tp*) in r-ebf422.o
"_Tp::fmt", referenced from:
split(char const*, _Tp*) in r-ebf422.o
"_Tp::str", referenced from:
split(char const*, _Tp*) in r-ebf422.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
What's more, when I tried to link some files, similar error happened.
clang -shared -o libmystdio.so myscanf.o myprintf.o
Undefined symbols for architecture arm64:
"_Tp::INT", referenced from:
split(char const*, _Tp*) in myscanf.o
split(char const*, _Tp*) in myprintf.o
"_Tp::fmt", referenced from:
split(char const*, _Tp*) in myscanf.o
split(char const*, _Tp*) in myprintf.o
"_Tp::str", referenced from:
split(char const*, _Tp*) in myscanf.o
split(char const*, _Tp*) in myprintf.o
"_Tp::LONG", referenced from:
split(char const*, _Tp*) in myscanf.o
split(char const*, _Tp*) in myprintf.o
"_Tp::LONGLONG", referenced from:
split(char const*, _Tp*) in myscanf.o
split(char const*, _Tp*) in myprintf.o
"_out_buf", referenced from:
myprintf(char const*, ...) in myprintf.o
"_out_idx", referenced from:
myprintf(char const*, ...) in myprintf.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [libmystdio.so] Error 1
In case you wonder what I've written, please click here. However it's not finished,I doubt you would be interested...(I made a few comments and most of them are in Chinese, for my groupmates to read)
And, files in folder code aren't affected. They can be compiled and run normally.Only those in folder code/myIO went wrong.
Here's my clang version:
clang -v
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: arm64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Thanks for your help in advance!
CodePudding user response:
You have a declaration without a definition.
utilities.h
has:
class _Tp {
// [...]
public:
// [...]
static const int INT = 1, SHORT = 2, LONG = 3, LONGLONG = 4,
FLOAT = 10, DOUBLE = 11, LONGDOUBLE = 12;
That declares _Tp::INT
etc. with initializers, but does not define them. If you ODR-use these values then you need to have a definition for them, meaning that there needs to be a single place designated to hold the bytes of memory for these constants in your program.[0]
The normal way to do this is to have a matching utilities.cpp
with:
const int _Tp::INT;
const int _Tp::SHORT;
const int _Tp::LONG;
const int _Tp::LONGLONG;
const int _Tp::FLOAT;
const int _Tp::DOUBLE;
const int _Tp::LONGDOUBLE;
but in your case you might want to consider switching to an enum! To do that you would write in utilities.h
:
class _Tp {
// [...]
public:
// [...]
enum { INT = 1, SHORT = 2, LONG = 3, LONGLONG = 4,
FLOAT = 10, DOUBLE = 11, LONGDOUBLE = 12 };
then you don't need a utilities.cpp
.
[0] There's a special-case for allowing values of integral types to be ODR-used without being defined in narrow circumstances, but I recommend that programmers not rely on it. A non-expert makes a innocent change to the code and gets a confusing link error.