EDIT2:
so here is an example of the program:
#include <stdio.h>
#include <ctype.h>
int main ()
{
int i=0;
char str[]="Test String.\n";
char c;
while (str[i])
{
c=str[i];
putchar (toupper(c));
i++;
}
return 0;
}
1) clang:
clang++ -std=c++0x -stdlib=libc++ -lc++ main.cc -o main
compiles fine.
2) g++-mp-4.8 -std=c++11 main.cc -o main
gives:
Undefined symbols for architecture x86_64:
"toupper(int)", referenced from:
_main in ccWjHauc.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
3) g++-mp-4.8 main.cc -o main
compiles!
any ideas what is wrong with the setup?
==========
Can someone help to understand what changed in Gcc/macports/os 10.9 ?
I used to have a compiling script of some third party library working in os 10.8. Recently I updated to the new osx (10.9) and gcc 4.7 from macports stopped linking. In particular I have:
Undefined symbols for architecture x86_64:
"isspace(int)", referenced from:
This problem is very similar to the one mentioned here for istype
.
However it seems isspace
does not sit in libgcc++.dylib.
Any ideas what to try?
EDIT1:
indeed, 4.8 fixed the problem with isspace
, but another surfaced - toupper
:
Undefined symbols for architecture x86_64:
"toupper(int)", referenced from: ...
What is going on here?!. Is it related to the new Xcode (5.0) ?
There's a patch in http://trac.macports.org/ticket/41033 It solved my problem. You just have to patch the file in /usr/include/sys/cdefs.h and replace
#elif defined(__GNUC__) && defined(__GNUC_STDC_INLINE__)
by
#elif defined(__GNUC__) && defined(__GNUC_STDC_INLINE__) && !defined(__cplusplus)
Good luck.
Most of the ctype.h
items are declared as inline definitions, so they get expanded at compile time. When you compile without -std=c++11
, it expands to:
extern inline int
toupper(int _c)
{
return (__toupper(_c));
}
When you compile with -std=c++11
, it expands to:
extern inline __attribute__((__gnu_inline__)) int
toupper(int _c)
{
return (__toupper(_c));
}
For some reason, g++ is then choosing to ignore the perfectly good definition that is presented there.
Based on the commentary on this invalid bug, it's gcc choosing to not optimize the code and looking for the definition in one of the linked libraries.
A workaround seems to be to compile with at least -O1
optimization, which avoids the issue, but it's a real pain in the ass.
Now when we look at the differences in the #defines between non-C++11 and C++11, we see that we have an extra #define:
$ touch x.cc
$ g++-4.9 -dM -E x.cc | grep STD
#define __STDC_HOSTED__ 1
#define __STDC__ 1
$ g++-4.9 -std=c++11 -dM -E x.cc | grep STD
#define __STDC_HOSTED__ 1
#define __GNUC_STDC_INLINE__ 1
#define __STDC__ 1
and because of a piece of code in the 10.9 SDK (usr/include/sys/cdefs.h
), all those __DARWIN_CTYPE_TOP_inline
in cytpe.h
get turned into __header_inline
which get turned into extern __inline __attribute__((__gnu_inline__))
thanks to this little bit of additional code:
#elif defined(__GNUC__) && defined(__GNUC_STDC_INLINE__)
# define __header_inline extern __inline __attribute__((__gnu_inline__))
It looks like apple's header is trying to do the right thing, but they've not covered all their bases. There is another issue, which mentions a similar bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With