2

Consider the following example:

#include <signal.h>

extern "C" {
    static void signalHandler(int signal) {}
}

int main(int, char**)
{
    sigset (SIGTERM, signalHandler);
    return 0;
}

CC test.cpp succeeds.

But

CC test.cpp -std=c++11
Undefined                       first referenced
 symbol                             in file
sigset                           test.o
ld: fatal: symbol referencing errors

I also tried the following:

CC test.cpp -std=c++11 -lstdc++ -lgcc_s -lc

But yields the same error. -m64 doesn't help either.

Nor does -lstdc++ -lgcc_s -lCrunG3.

OS: Solaris 11 Compiler: CC from Oracle Solaris Studio 12.4

Output requested:

me@myhost:~/projects/cpptest> CC -std=c++11 -c test.cpp -o test.o
me@myhost:~/projects/cpptest> nm -A test.o | grep sigset
test.o: [14]    |         0|         0|FUNC |GLOB |0    |UNDEF  |_Z6sigset
me@myhost:~/projects/cpptest> nm -A /usr/lib/libc.so | grep sigset
/usr/lib/libc.so: [527] |    883372|       224|FUNC |LOCL |2    |16     |__csigsetjmp
/usr/lib/libc.so: [5694]        |    736724|       420|FUNC |WEAK |3    |16     |_sigset
/usr/lib/libc.so: [6599]        |    883868|        28|FUNC |GLOB |3    |16     |_sigsetjmp
/usr/lib/libc.so: [4906]        |    833680|       532|FUNC |WEAK |3    |16     |_thr_sigsetmask
/usr/lib/libc.so: [6267]        |    736724|       420|FUNC |GLOB |3    |16     |sigset
/usr/lib/libc.so: [4590]        |    883868|        28|FUNC |GLOB |3    |16     |sigsetjmp
/usr/lib/libc.so: [2244]        |         0|         0|FILE |LOCL |0    |ABS    |sigsetops.c
/usr/lib/libc.so: [4502]        |    833680|       532|FUNC |GLOB |3    |16     |thr_sigsetmask
me@myhost:~/projects/cpptest>

If I use <csignal> instead of <signal.h>, I get the following error:

"test.cpp", line 17: Error: The function "sigset" must have a prototype.
otisonoza
  • 1,334
  • 2
  • 14
  • 32
  • 1
    Hasn't this been asked just about ten minutes ago? – cadaniluk Nov 04 '15 at 16:15
  • @cad...umm, i think 23 minutes... – Sourav Ghosh Nov 04 '15 at 16:16
  • 1
    @cad, you know something more strange. I have seen this kind of trend from a week. May be some students from the same class are here. Asking similar questions regarding their work. – Haris Nov 04 '15 at 16:19
  • @SouravGhosh Whatever, I hope my point's clear anyway. :-) – cadaniluk Nov 04 '15 at 16:21
  • 1
    I deleted *my* question (I think I'm *allowed* to do it) because in the meanwhile I found out it's not specific to linking, and can be reproduced by a small example. So I opened a (in my opinion) better question to avoid the "show me your code" and "show me the compiler flags" questions. And I'm at a workplace so I coudln't provide the exact information. – otisonoza Nov 04 '15 at 16:23
  • 1
    From the "***CONFORMING TO***" section of a recent Linux man-page for `sigset()`: "*SVr4, POSIX.1-2001. These functions are obsolete: do not use them in new programs. POSIX.1-2008 marks sighold(), sigignore(), sigpause(), sigrelse(), and sigset() as obsolete, recommending the use of sigaction(2), sigprocmask(2), pthread_sigmask(3), and sigsuspend(2) instead.*" – alk Nov 04 '15 at 16:59
  • For completeness the current POSIX page on this: http://pubs.opengroup.org/onlinepubs/9699919799/functions/sighold.html – alk Nov 04 '15 at 17:03
  • @alk - But `sigset()` still exists in Solaris 11: http://docs.oracle.com/cd/E23824_01/html/821-1465/sigset-3c.html#scrolltoc The fact that it's obsolete doesn't mean it doesn't exist. The `sigset()` call will still exist in the library, even if only to support legacy applications. I don't have access to Solaris 11 right now, but I suspect a non-demangled name dump of the object file from `CC -std=c++11 -c test.cpp -o test.o` might be illuminating. – Andrew Henle Nov 04 '15 at 18:20
  • @otisonoza, If you run `CC -std=c++11 -c test.cpp -o test.o`, what's the output from `nm -A test.o | grep sigset`? And what's the output from `nm -A /usr/lib/libc.so | grep sigset`? – Andrew Henle Nov 04 '15 at 22:19
  • As remember there is some problem with Solaris's includes, and I have to include both `signal.h` and `csignal`, but it was related to `kill`. May be this helps also for sigset, try also `std::sigset` – fghj Nov 05 '15 at 11:05
  • @user1034749 : Thanks for the hint. Unfortunately, it doesn't help. – otisonoza Nov 05 '15 at 11:58
  • It looks like, when given the `-std=c++11` option, CC will generate mangled names for any var that's a function pointer, even when it's in an `extern "C"` block. Try compiling this with `-c` and then running `nm` on the .o file: `extern "C" { void (*foo()); } int main(int, char**) { foo(); }` . And `sigset` is one of the few C library functions whose type is a function pointer. `extern void (*sigset(int, void (*)(int)))(int);` – Mark Plotnick Nov 05 '15 at 19:23
  • @MarkPlotnick It's either a C++11 compiler bug or a problem with the system include files failing to declare `sigset()` as `extern "C"`. Given the problem only appears when using `-std=c++11`, I'd bet on a compiler bug. If you don't have an Oracle support contract and can't file a bug report, you might want to post the problem here: https://community.oracle.com/community/server_%26_storage_systems/application_development_in_c__c%2B%2B__and_fortran/solaris_studio_c_c%2B%2B_fortran_compilers – Andrew Henle Nov 06 '15 at 11:11
  • @AndrewHenle Thanks. I ran OP's program through `CC -E`. In the preprocessed output, `sigset` is declared `extern "C"`, whether or not the `-std=c++11` option is given. I think it's either a compiler bug or there's some rule in C++11 that says these types shall unconditionally have C++ linkage. – Mark Plotnick Nov 06 '15 at 15:07

0 Answers0