Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#41033 closed defect (fixed)

cctype functions (e.g. isprint) not defined at link time when using g++ -std=c++11

Reported by: eschnett (Erik Schnetter) Owned by: jeremyhu (Jeremy Huddleston Sequoia)
Priority: Normal Milestone:
Component: ports Version: 2.2.1
Keywords: Cc: davydden@…, jeremyhu (Jeremy Huddleston Sequoia), akimd (Akim Demaille), etienne.renault@…, ghlecl (Ghyslain Leclerc), fang@…, NeilGirdhar (Neil), egpbos@…, larryv (Lawrence Velázquez), cooljeanius (Eric Gallager), macports@…
Port: gcc48

Description

I am using Mavericks, and I have C++ code that I want to build with GCC 4.8 and with the option -std=c++1. This code used std::isprint. The code builds fine, but at link time I receive the error message that isprint(int) is not defined.

This code can reproduce the problem:

#include <cctype>
int main(int argc, char** argv)
{
  std::isprint('a');
  return 0;
}

Build it with:

g++ -std=c++11 -o isprint isprint.cc

and the linker will complain:

$ g++ -std=c++11 -o isprint isprint.cc
Undefined symbols for architecture x86_64:
  "isprint(int)", referenced from:
      _main in cc2AhhUM.o
ld: symbol(s) not found for architecture x86_64

The problem is that the system file /usr/include/sys/cdefs.h mis-uses a GCC extension handling the "inline" keyword. This file needs to be updated to not do so when called from C++. This patch does just this:

$ diff -u /usr/include/sys/cdefs.h /opt/local/lib/gcc48/gcc/x86_64-apple-darwin13/4.8.1/include-fixed/sys/cdefs.h 
--- /usr/include/sys/cdefs.h	2013-10-23 14:56:58.000000000 -0400
+++ /opt/local/lib/gcc48/gcc/x86_64-apple-darwin13/4.8.1/include-fixed/sys/cdefs.h	2013-10-28 15:28:05.000000000 -0400
@@ -216,7 +225,7 @@
 
 #if __STDC_VERSION__ >= 199901L && (!defined(__GNUC__) || defined(__clang__))
 # define __header_inline           inline
-#elif defined(__GNUC__) && defined(__GNUC_STDC_INLINE__)
+#elif defined(__GNUC__) && defined(__GNUC_STDC_INLINE__) && !defined(__cplusplus)
 # define __header_inline           extern __inline __attribute__((__gnu_inline__))
 #elif defined(__GNUC__)
 # define __header_inline           extern __inline

With this modification, and with the modified file installed into /opt/local/lib/gcc48/gcc/x86_64-apple-darwin13/4.8.1/include-fixed/sys/cdefs.h, the sample program builds fine.

I suggest to update gcc-4.8 in this way, i.e. to fix-include /usr/include/sys/cdefs.h in this way.

I assume that gcc-4.7 and maybe other, earlier versions are affected as well.

Change History (25)

comment:1 Changed 10 years ago by ryandesign (Ryan Carsten Schmidt)

Owner: changed from macports-tickets@… to mww@…

comment:2 Changed 10 years ago by davydden@…

Cc: davydden@… added

Cc Me!

comment:3 Changed 10 years ago by ryandesign (Ryan Carsten Schmidt)

Obviously, if you want a change to be made to a system header, the people you have to report that to are Apple, not MacPorts.

comment:4 Changed 10 years ago by jeremyhu (Jeremy Huddleston Sequoia)

Yes, please do file a radar.

Also, I don't think that patch is quite the correct change.

comment:5 Changed 10 years ago by jeremyhu (Jeremy Huddleston Sequoia)

Summary: cctype functions (e.g. isprint) not defined at link timecctype functions (e.g. isprint) not defined at link time when using g++ -std=c++11

Also note that this isn't an issue unless using g++ -std=c++11. clang++ -std=c++11 works fine, and g++ (without -std=c++11) works fine. While we can certainly find a workaround for this in the system headers, what you're trying to do is not really a supported configuration.

comment:6 Changed 10 years ago by jeremyhu (Jeremy Huddleston Sequoia)

Cc: jeremyhu@… added

Cc Me!

comment:7 Changed 10 years ago by jeremyhu (Jeremy Huddleston Sequoia)

Owner: changed from mww@… to jeremyhu@…
Status: newassigned

comment:8 Changed 10 years ago by jeremyhu (Jeremy Huddleston Sequoia)

Looks like this is fallout from our workaround for gcc's bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55965). I think the fix is to just not do that workaround for C++.

comment:9 Changed 10 years ago by jeremyhu (Jeremy Huddleston Sequoia)

Inline is such a PITA. I think this is what it should be. Please feel free to chime in. If you see issues, please provide test cases or links to references:

#if defined(__cplusplus) || \
    (__STDC_VERSION__ >= 199901L && \
     !defined(__GNUC_GNU_INLINE__) && \
     (!defined(__GNUC__) || defined(__clang__)))
# define __header_inline           inline
#elif defined(__GNUC__) && defined(__GNUC_STDC_INLINE__)
# define __header_inline           extern __inline __attribute__((__gnu_inline__))
#elif defined(__GNUC__)
# define __header_inline           extern __inline
#else
  /* If we land here, we've encountered an unsupported compiler,
   * so hopefully it understands static __inline as a fallback.
   */
# define __header_inline           static __inline
#endif

comment:10 Changed 10 years ago by akimd (Akim Demaille)

Cc: akim.demaille@… added

Cc Me!

comment:11 in reply to:  10 ; Changed 10 years ago by etienne.renault@…

Cc Me!

Last edited 10 years ago by etienne.renault@… (previous) (diff)

comment:12 in reply to:  11 Changed 10 years ago by larryv (Lawrence Velázquez)

Cc: etienne.renault@… added

You need to actually click the “CcMe!” button.

comment:13 Changed 10 years ago by ghlecl (Ghyslain Leclerc)

Cc: ghleclerc@… added

Cc Me!

comment:14 Changed 10 years ago by ghlecl (Ghyslain Leclerc)

I don't know if it's relevant, but I'll had my experience. I have run into the same problem trying to compile ITK (Insight Toolkit) on OSX 10.9 Maverick using the Macports installed gcc 4.8 and the -std=c++11 option. Copying the system cdefs.h file and applying the fix suggested by the original poster of this report worked and allowed compilation to finish.

I installed my gcc version last night (2013-11-20) on a clean system install (wiped my Mountain Lion and reinstalled Maverick) with up-to-date port definitions.

In short, on 2013-11-21, the problem seems to still be there and the original suggested fix worked for me.

comment:15 Changed 10 years ago by ghlecl (Ghyslain Leclerc)

Again, might not be relevant (my apologies), but I've rebuilt ITK using the second proposed fix this time (by Jeremy Hu). It also works. Just thought I'd let people know.

comment:16 Changed 10 years ago by fang@…

Cc: fang@… added

Cc Me!

comment:17 Changed 10 years ago by NeilGirdhar (Neil)

Cc: mistersheik@… added

Cc Me!

comment:18 Changed 10 years ago by egpbos@…

Cc: egpbos@… added

Cc Me!

comment:19 Changed 10 years ago by egpbos@…

My problem was with tolower(int), also from ctype.h. Also using GCC 4.8 (MacPorts gcc48 4.8.2_0) with -std=c++11 option.

Original poster's fix works for me too.

comment:20 Changed 10 years ago by jeremyhu (Jeremy Huddleston Sequoia)

Yes, you're going to have to workaround it like that for now if you need C++11 support in g++.

Note that I strongly urge anyone doing C++11 work to use clang++ with libc++. If there is a reason that won't work, let me know.

comment:21 Changed 10 years ago by larryv (Lawrence Velázquez)

Cc: larryv@… added

Cc Me!

comment:22 Changed 10 years ago by cooljeanius (Eric Gallager)

Cc: egall@… added

Cc Me!

comment:23 Changed 10 years ago by macports@…

Cc: macports@… added

Cc Me!

comment:24 Changed 10 years ago by jeremyhu (Jeremy Huddleston Sequoia)

Resolution: fixed
Status: assignedclosed

Fixed in Xcode 5.1

comment:25 Changed 10 years ago by cooljeanius (Eric Gallager)

Also, for people that have not updated to Xcode 5.1 yet, you can use the gl_EXTERN_INLINE m4 macro from the extern-inline.m4 file from gnulib/gettext to check for this bug in your configure script. The most recent version of gettext will automatically call this macro for you as long as you use AM_GNU_GETTEXT([external]) and AM_GNU_GETTEXT_VERSION([0.18.3]) in your configure.ac file. See the following gnulib mailing list discussion for more on the relationship between this autoconf macro and this bug: http://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html

Version 0, edited 10 years ago by cooljeanius (Eric Gallager) (next)
Note: See TracTickets for help on using tickets.