Solved Stuck With Strange Compiler Complaint (_POSIX_SOURCE macro)

Hello, folks.

I'm trying to upgrade a port I made years ago. But I'm stuck. I'm not a skilled C++ developer, so I really need help to figure out what to do here. I'm trying RTFM with no luck for days... and I spent a lot of time porting new dependencies for this app first.

What encourages me to ask is an simple code example I found in a gcc bug track, that raises quite the same error. So I don't understand if it is something related to the compiler ( a bug), or something that needed a patch (porting) or even a good and old workaround !

I have the same problem whatever using c++ or g++ .

The compiler stops with this file:

transmitter.h :

Code:
#ifndef __libmisc_transmitter_h__
#define __libmisc_transmitter_h__

//#include <wchar.h> //testing
#include <sstream> //THIS IS LINE 24, where c++ or g++ complains
#include <iostream>

#include <pbd/signals.h>

#include "pbd/libpbd_visibility.h"

//using namespace std; //testing

class LIBPBD_API Transmitter : public std::stringstream
{

... more code


Raising this error (a hint, it repeats a lot until stop reaching err limit):


Code:
[846/881] cxx: libs/fst/scanner.cc -> build/libs/fst/scanner.cc.1.o
In file included from ../libs/fst/scanner.cc:9:
In file included from /usr/home/marcelbonnet/devel/ports/PORTS/audio/ardour-devel/work/ardour-devel-5.3/libs/pbd/pbd/transmitter.h:24:
In file included from /usr/include/c++/v1/sstream:174:
In file included from /usr/include/c++/v1/ostream:138:
In file included from /usr/include/c++/v1/ios:216:
In file included from /usr/include/c++/v1/__locale:15:
In file included from /usr/include/c++/v1/string:437:
/usr/include/c++/v1/cstdio:143:9: error: no member named 'snprintf' in the global namespace

using ::snprintf;
~~^
/usr/include/c++/v1/cstdio:148:9: error: no member named 'vfscanf' in the global namespace; did you mean 'fscanf'?
using ::vfscanf;
~~^
/usr/include/stdio.h:248:6: note: 'fscanf' declared here
int fscanf(FILE * __restrict, const char * __restrict, ...);
^
In file included from ../libs/fst/scanner.cc:9:
In file included from /usr/home/marcelbonnet/devel/ports/PORTS/audio/ardour-devel/work/ardour-devel-5.3/libs/pbd/pbd/transmitter.h:24:
In file included from /usr/include/c++/v1/sstream:174:
In file included from /usr/include/c++/v1/ostream:138:
In file included from /usr/include/c++/v1/ios:216:
In file included from /usr/include/c++/v1/__locale:15:
In file included from /usr/include/c++/v1/string:437:
/usr/include/c++/v1/cstdio:149:9: error: no member named 'vscanf' in the global namespace
using ::vscanf;
~~^
/usr/include/c++/v1/cstdio:150:9: error: no member named 'vsscanf' in the global namespace; did you mean 'sscanf'?
using ::vsscanf;
~~^
/usr/include/stdio.h:268:6: note: 'sscanf' declared here
int sscanf(const char * __restrict, const char * __restrict, ...);
^



I'm really lost, since I see it happens out of this port, while trying to find an answer. I can't neither compile this simple program too (found here https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24012 ):


Code:
#define _POSIX_C_SOURCE 1
#include <iostream>
using namespace std;

int main () {

return 0;

}


Or this variation I made:


Code:
//#include <wchar.h> //works adding this include and preserving the next include
#define _POSIX_C_SOURCE 1
#include <iostream>
using namespace std;

int main () {
int x = 10;
int y = 20;
{
int x; // ok, inner scope.
x = 50; // sets value to inner x
y = 50; // sets value to (outer) y
cout << "inner block:\n";
cout << "x: " << x << '\n';
cout << "y: " << y << '\n';
}

cout << "outer block:\n";
cout << "x: " << x << '\n';
cout << "y: " << y << '\n';
return 0;

}


The error of the code above:

Code:
In file included from teste.cpp:3:
In file included from /usr/include/c++/v1/iostream:38:
In file included from /usr/include/c++/v1/ios:216:
In file included from /usr/include/c++/v1/__locale:15:
In file included from /usr/include/c++/v1/string:437:
/usr/include/c++/v1/cstdio:143:9: error: no member named 'snprintf' in the global namespace
using ::snprintf;
~~^
/usr/include/c++/v1/cstdio:148:9: error: no member named 'vfscanf' in the global namespace; did you mean 'fscanf'?
using ::vfscanf;
~~^
/usr/include/stdio.h:248:6: note: 'fscanf' declared here
int fscanf(FILE * __restrict, const char * __restrict, ...);
^
In file included from teste.cpp:3:
In file included from /usr/include/c++/v1/iostream:38:
In file included from /usr/include/c++/v1/ios:216:
In file included from /usr/include/c++/v1/__locale:15:
In file included from /usr/include/c++/v1/string:437:
/usr/include/c++/v1/cstdio:149:9: error: no member named 'vscanf' in the global namespace
using ::vscanf;
~~^
/usr/include/c++/v1/cstdio:150:9: error: no member named 'vsscanf' in the global namespace; did you mean 'sscanf'?
using ::vsscanf;
~~^
/usr/include/stdio.h:268:6: note: 'sscanf' declared here
int sscanf(const char * __restrict, const char * __restrict, ...);
^
...

I'd appreciate a little help.
 
The keyword of the issue is:
Code:
#define POSIX_C_SOURCE 1
what's that ?
It is the way a developer can tell the program requirements to the compiler:
a) the compiler must provide a feature like defined from that POSIX standard
b) even if the compiler provide additional features, related to later standards, should NOT use them because the author want the program be portable, and thus should build without any "POSIX compliance" added later.

Code:
      _POSIX_C_SOURCE
              Defining this macro causes header files to expose definitions as
              follows:

              o  The value 1 exposes definitions conforming to POSIX.1-1990
                 and ISO C (1990).

              o  The value 2 or greater additionally exposes definitions for
                 POSIX.2-1992.
 
             ... and more
See also: https://www.freebsd.org/cgi/man.cgi?query=feature_test_macros&manpath=SuSE+Linux/i386+11.3

Note that this macro, if present must be added before any #include directive, by including <wchar> before that directive you circumvent its scope, most likely because <wchar> header will include additional headers before the compiler can see the POSIX requirement directive.

POSIX compliance is implemented in compiler by two primary changes: headers file and stdc library.

A further note: you wrote:
#include <sstream> //THIS IS LINE 24, where c++ or g++ complains
No, the source of the error is <cstdio> header, like described in the error message:
/usr/include/c++/v1/cstdio:143:9: error: no member named 'snprintf' in the global namespace
what is listed above the error is the sequence of nested inclusion of several headers file, up to the original source file that most likely will include some POSIX_SOURCE directive.

Looking into <cstdio> header, those missing functions declarations are commented with // C99, and effectively the corresponding man page state they are compliant with: "conform to ISO/IEC 9899:1999 (“ISO C99”). See in example vscanf(3)

Of course, there seems to be a bug around that POSIX compliance still open as far as I can see... but considering that the POSIX compliance requirement are quite low .. 1990 ... I would suspect that all the required features are there.

(I will not discuss why there is this bug, because I don't know and because it is outside the scope of my answer here).

Additionally, you are only porting the program to FreeBSD, you aren't writing the program, and you are not interested to force any compliance, your target is to make it compile and work properly on FreeBSD.

Considering all the above, you can remove that #define POSIX_C_SOURCE 1 directive, and your program should compile just fine, at least that is what I was able to achieve by compiling your examples using CLANG c++.

Hope that help.
(I'm not a C++ expert too, but have some experience with C development.)
 
ASX , thanks a lot! ;)

Though, I have to say I'm sorry I for not exposing the complete CPP file , a git url, whatever file I'm trying to port (too much things in my head the moment I opened this thread, I did not ask right, just shown the problem!), but I'm sure you gave a lot of new information. I will read it again, follow your links and redo things...

More important than get the answer is to have a new ideia to go on. Thanks. To be honest, I was not expecting any comment to this thread!
 
Don't worry, the question was understandable, and my answer is only a starting point. If something is not clear, please ask.
 
;) Thanks again. I read that man page and I think you guide me to solve it. My machine is too slow, so it will take hours to stuck again or to finish compilation... but, you made me realize that:

_POSIX_C_SOURCE 1 is the same as _POSIX_SOURCE, which I found in various waf scripts set by the upstream. Now I removed this macro from wscript files, and I'm longing to see what happens!
 
Didn't expected it! :D In my experience, porting software require at least a few build cycles, glad it worked! :)
 
Back
Top