11

I have written a multithread server program in C, which echoes back all the data that a client sends.

Initially, I used poll() function in my program to detect POLLRDHUP event, for that I defined _GNU_SOURCE macro (This event is defined here).

Later I updated my code & removed poll() function, however I forgot to remove _GNU_SOURCE macro.

Now my code is finally complete (and a little long to post, more than 250 lines). Before removing macro I was compiling my program using:

gcc multi_thread_socket_v4.c -Wall -Werror -g -lpthread -o multi_thread_socket

and it worked fine: No errors, no warnings

After I removed the macro definition, and compiled using same command-line, the output of gcc was:

multi_thread_socket_v4.c: In function ‘main’:
multi_thread_socket_v4.c:194: warning: implicit declaration of function ‘pthread_mutexattr_settype’
multi_thread_socket_v4.c:194: error: ‘PTHREAD_MUTEX_ERRORCHECK’ undeclared (first use in this function)
multi_thread_socket_v4.c:194: error: (Each undeclared identifier is reported only once
multi_thread_socket_v4.c:194: error: for each function it appears in.)

I have included all the required libraries as it worked fine initially.

I peeked into pthread.h at /usr/include/pthread.h and found out this:

/* Mutex types.  */
enum
{
  PTHREAD_MUTEX_TIMED_NP,
  PTHREAD_MUTEX_RECURSIVE_NP,
  PTHREAD_MUTEX_ERRORCHECK_NP,
  PTHREAD_MUTEX_ADAPTIVE_NP
#ifdef __USE_UNIX98
  ,
  PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
  PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
  PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
  PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
#endif
#ifdef __USE_GNU
  /* For compatibility.  */
  , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
#endif
};

and this:

#ifdef __USE_UNIX98
/* Return in *KIND the mutex kind attribute in *ATTR.  */
extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict
                      __attr, int *__restrict __kind)
     __THROW __nonnull ((1, 2));

/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
   PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
   PTHREAD_MUTEX_DEFAULT).  */
extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
     __THROW __nonnull ((1));

I checked out here to check if __USE_UNIX98 is a feature test macro, but it was not there.

So please help me understanding the reasons for the error, because the function & the macro where gcc shows error are defined in POSIX standard. I do not know what more info regarding my problem will be required so please tell me, I will update my question.

0xF1
  • 6,046
  • 2
  • 27
  • 50
  • The most obvious answer is that the feature is not in Posix, but only in Linux. By default, the pthread library tries to be Posix conforming. – Kerrek SB Aug 22 '13 at 08:44
  • Also note that double-underscore macros aren't for you to use; they're reset internally. You can only use top-level macros like `_GNU_SOURCE` and `_BSD_SOURCE` to control which parts of the library are pulled in. – Kerrek SB Aug 22 '13 at 08:45
  • @KerrekSB : But the function `pthread_setattr_settype()` & the macro `PTHREAD_MUTEX_ERRORCHECK` are [POSIX standard](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_gettype.html), so why they need `_GNU_SOURCE` to be defined? – 0xF1 Aug 22 '13 at 09:03
  • But they aren't standard C, so they need *something* to be defined ... not necessarily _GNU_SOURCE, which is a kitchen sink define that drags in lots of stuff. – Jim Balter Aug 22 '13 at 09:45

3 Answers3

9

You should use

#define _POSIX_C_SOURCE 200112L

if you want to use POSIX features such as pthread_mutexattr_settype ... see http://pubs.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_02.html

Another possibility is

#define _XOPEN_SOURCE 700

See http://man7.org/linux/man-pages/man7/feature_test_macros.7.html and http://pubs.opengroup.org/onlinepubs/9699919799/

Setting _GNU_SOURCE includes POSIX and lots of other definitions.

P.S. I would expect that including <pthread.h> includes <features.h>, which by default defines _POSIX_C_SOURCE as 200112L, but it's possible that you have defined something that overrides that ... see /usr/include/features.h on your system for details of the symbols and their usage.

Jim Balter
  • 16,163
  • 3
  • 43
  • 66
  • Got your point, will read them. By the way [this link I found](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html) is more recent standard revision. – 0xF1 Aug 22 '13 at 09:56
  • @nishant That link is within the one I gave. I don't really think you need to read them, you just need to provide the defines. What I'm doing here is answering your question. – Jim Balter Aug 22 '13 at 10:00
  • Thanks, although `_XOPEN_SOURCE 700` did the trick (so did the `_GNU_SOURCE`). but won't it affect other functions also? I mean may be other functions start behaving differently. – 0xF1 Aug 22 '13 at 10:05
  • @nishant Mostly it affects what symbols are visible, not behavior. You could get behavior changes if you were explicitly asking for older obsolescent versions of standards. – Jim Balter Aug 22 '13 at 10:08
0

It doesn't, your problem likely lies elsewhere.

I just compiled a trivial program with the following content:

#include <pthread.h>

int main(int argc, char **argv)
{
    pthread_mutexattr_t attr;

    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);

    return 0;
}

This compiles perfectly with gcc -pthread -Wall -Werror a.c.

It's possible that another part of your program causes this, by eg. doing something silly like defining _PTHREAD_H, or some other minor sabotage.

You might want to try to get a minimal test case by using a tool like delta or creduce, which will probably make the problem evident.

Hasturkun
  • 35,395
  • 6
  • 71
  • 104
  • 1
    Your code gives same error on my machine. Machine specs: Operating System: SLES 10 SP3 x86-64. – 0xF1 Aug 22 '13 at 09:47
  • @nishant There are other answers here. Try mine. – Jim Balter Aug 22 '13 at 09:49
  • @nishant: That's quite strange. I've built this on a vanilla debian install. AFAIK, you shouldn't have to explicitly define any feature macros, as `features.h` included from `pthread.h` should define these if nothing else was defined (which is why this compiles here, which I just checked using `gcc -E -fdirectives-only`.) – Hasturkun Aug 22 '13 at 09:58
  • I'll also note that setting some things will break this, eg. defining `__STRICT_ANSI__ ` (by way of the `-ansi` flag), or `_POSIX_SOURCE` or `_POSIX_C_SOURCE`. (in my case, this ends up setting `__USE_XOPEN2K8` which enables the function) – Hasturkun Aug 22 '13 at 10:06
  • I studied the output of `gcc file.c -E -fdirectives-only` but nowhere there, `__USE_UNIX98` was defined. However after `#define _XOPEN_SOURCE 700` this line `#define __USE_UNIX98` was there at the end. – 0xF1 Aug 22 '13 at 10:20
0

When you're using old libraries (e.g. 2.1.x) you should use

#define __USE_UNIX98

Using a macro beginning with "__" it's not usually a good idea, but sometimes it's the only way... see also this discussion

General Failure
  • 2,421
  • 4
  • 23
  • 49
Emilio
  • 29
  • 1
  • 2