How to force g++ to respect #define _POSIX_C_SOURCE 200809L

Ingo

I need to use strerror_r to translate error numbers into human readable messages compiled with g++ on Linux Debian Bullseye. The man page notes:

int strerror_r(int errnum, char *buf, size_t buflen);
           /* XSI-compliant */

char *strerror_r(int errnum, char *buf, size_t buflen);
           /* GNU-specific */

strerror_r():
   The XSI-compliant version is provided if:
   (_POSIX_C_SOURCE >= 200112L) && !  _GNU_SOURCE
   Otherwise, the GNU-specific version is provided.

We have two different types of the return value: int or char* depending on the version defined by _POSIX_C_SOURCE. I have this small test program:

~$ cat strerror_r.c
#include <string.h>
#include <stdio.h>

// #define _POSIX_C_SOURCE 200112L
// #undef _GNU_SOURCE

#define ERROR_BUFFER_LEN (size_t)256

int main(int argc, char **argv)
{
#if _POSIX_C_SOURCE < 200112L
    char* ret;
#else
    int ret;
#endif
    char errorBuffer[ERROR_BUFFER_LEN];
    int errno;

    errno = 0;
    ret = strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
    fprintf(stderr, "Error message by pointer = '%s'\n", ret);
    fprintf(stderr, "Content of errorBuffer =  '%s'\n", errorBuffer);

    return 0;
}

If I compile it with gcc everything is as expected:

$ gcc strerror_r.c && ./a.out; rm a.out
Error message by pointer = '(null)'
Content of errorBuffer =  'Success'

If I compile it with g++ I get this:

$ g++ strerror_r.c && ./a.out; rm a.out
strerror_r.c: In function ‘int main(int, char**)’:
strerror_r.c:24:21: error: invalid conversion from ‘char*’ to ‘int’ [-fpermissive]
   24 |     ret = strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
      |           ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                     |
      |                     char*
rm: cannot remove 'a.out': No such file or directory

If I try to force the needed version by uncommenting

#define _POSIX_C_SOURCE 200112L
#undef _GNU_SOURCE

I get:

$ g++ strerror_r.c && ./a.out; rm a.out
strerror_r.c:7: warning: "_POSIX_C_SOURCE" redefined
    7 | #define _POSIX_C_SOURCE 200112L
      |
In file included from /usr/include/x86_64-linux-gnu/bits/libc-header-start.h:33,
                 from /usr/include/string.h:26,
                 from strerror_r.c:3:
/usr/include/features.h:281: note: this is the location of the previous definition
  281 | # define _POSIX_C_SOURCE 200809L
      |
strerror_r.c: In function ‘int main(int, char**)’:
strerror_r.c:24:21: error: invalid conversion from ‘char*’ to ‘int’ [-fpermissive]
   24 |     ret = strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
      |           ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                     |
      |                     char*
rm: cannot remove 'a.out': No such file or directory

What I'm missing here? Why g++ does not compile the default thread save version of strerror_r? I need that version. How can I fix it?


Reference

bk2204

You need to specify the #define and #undef directives before you include any header files, so the first few lines should look like this:

#define _POSIX_C_SOURCE 200112L
#undef _GNU_SOURCE

#include <string.h>
#include <stdio.h>

That's because those header files or internal header files they include need those values defined to choose the proper variant. If you define them after including the headers, the headers don't see the right values and they don't include the version you want.

Often people specify these values on the command like with the -D and -U arguments so they are always specified before header files are included.

Collected from the Internet

Please contact javaer1[email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

in contrast to C code, why C++ code doesn't need "#define _POSIX_C_SOURCE 200809L"?

How to know to which value I should define _POSIX_C_SOURCE?

how define a new column with respect of 4 columns?

how to define an indicator with respect of 4 columns?

How to force autoconf to not define a macro?

How to force "Respect Language Direction" from RTL to LTR and vice versa

How to force Ruby to respect underscore in Net::HTTP header

How to force `img` tag to respect parent `picture` parameters?

How can I define an abstract odd function in mathematica? With respect to derivatives

How to define a custom li element with respect to accessability requirements?

How to make g++ force me to adhere to C++ standard

How to force g++ to compile c++11 standard only?

How to force g++ to inline STL functions

How to force responsive iframe target to respect viewport of iframe and behave responsively as if it were being accessed directly?

How to force Prettier to use always quote props (and respect my eslint rules)?

Where is g struct define in golang source code?

how to define an abstract class in python and force implement variables

How do I force a Java subclass to define an Annotation?

Force PHP newline to respect current indentation level

Force bash to respect newlines in command output

Force rdflib to define a namespace

Does C++ force me to define a default constructor

How to define an array in C

How to force OpenLayers to load source?

How to force npm bin -g to print only the path

How to force Nsight Eclipse to use an older version of gcc/g++?

How does C++ handle template functions with respect to type conversions

C# : Selenium : How to find an element with respect to the innertext of another element

How structure padding is works with respect to largest size member in C?