The compiler's C++ headers do not appear to work properly on AIX when the compiler is run with -D_LARGE_FILES. This macro causes the system headers to #define symbols like fopen, while the C++ headers unconditionally #undef these symbols. Environment: System: AIX bigblue 2 5 000F699D4C00 host: powerpc-ibm-aix5.2.0.0 build: powerpc-ibm-aix5.2.0.0 target: powerpc-ibm-aix5.2.0.0 configured with: /usr0/slammert/gcc-3.4.3/configure --with-as=/usr/bin/as --with-ld=/usr/bin/ld --disable-nls --enable-languages=c,c++ --enable-threads --enable-version-specific-runtime-libs How-To-Repeat: On AIX 5.2, compile the following program with 3.4.3 g++ -D_LARGE_FILES: #include <iostream> int main(void) { return 0; } You will get output similar to the following: In file included from /usr/local/lib/gcc/powerpc-ibm-aix5.2.0.0/3.4.3/include/c++/powerpc-ibm-aix5.2.0.0/bits/c++locale.h:43, from /usr/local/lib/gcc/powerpc-ibm-aix5.2.0.0/3.4.3/include/c++/iosfwd:46, from /usr/local/lib/gcc/powerpc-ibm-aix5.2.0.0/3.4.3/include/c++/ios:44, from /usr/local/lib/gcc/powerpc-ibm-aix5.2.0.0/3.4.3/include/c++/ostream:45, from /usr/local/lib/gcc/powerpc-ibm-aix5.2.0.0/3.4.3/include/c++/iostream:45, from bug0.C:1: /usr/local/lib/gcc/powerpc-ibm-aix5.2.0.0/3.4.3/include/c++/cstdio:108: error: `::fgetpos' has not been declared /usr/local/lib/gcc/powerpc-ibm-aix5.2.0.0/3.4.3/include/c++/cstdio:110: error: `::fopen' has not been declared /usr/local/lib/gcc/powerpc-ibm-aix5.2.0.0/3.4.3/include/c++/cstdio:115: error: `::freopen' has not been declared /usr/local/lib/gcc/powerpc-ibm-aix5.2.0.0/3.4.3/include/c++/cstdio:118: error: `::fsetpos' has not been declared
Fix: I can work around this problem and still compile a program with a 64-bit off_t by compiling with -maix64 instead of -D_LARGE_FILES.
G++ and libstdc++ on AIX currently is configured to enable _LARGE_FILE_API, but not _LARGE_FILES. _LARGE_FILE_API exposes the 64-bit functions with separate names off64_t and fopen64(), but does not redefine the original functions with their counterparts supporting 64-bit types.
Any plans to add _LARGE_FILES support to g++/libstdc++ for AIX?
Same here with gcc-4.2.2 and powerpc-ibm-aix5.3.0.0. Some diagnostics what happens when _LARGE_FILES (and _LARGE_FILE_API) is defined: <sys/types.h> /* would both be 'long' without _LARGE_FILES: */ typedef long long fpos_t; typedef long long off_t; /* because of _LARGE_FILE_API: */ typedef long long off64_t; <stdio.h> /* because of _LARGE_FILES (the 'problematic' ones): */ #define fseeko fseeko64 #define ftello ftello64 #define fgetpos fgetpos64 #define fsetpos fsetpos64 #define fopen fopen64 #define freopen freopen64 /* these actually are declared as f*64() because of defines above: */ extern FILE *fopen(const char *, const char *); extern FILE *freopen(const char *, const char *, FILE *); extern int fgetpos(FILE *, fpos_t *); extern int fsetpos(FILE *, const fpos_t *); extern int fseeko(FILE *, off_t, int); extern off_t ftello(FILE *); /* because of _LARGE_FILE_API: */ extern int fgetpos64(FILE *, fpos64_t *); extern FILE *fopen64(const char *, const char *); extern FILE *freopen64(const char *, const char *, FILE *); extern int fseeko64(FILE *, off64_t, int); extern int fsetpos64(FILE *, const fpos64_t *); extern off64_t ftello64(FILE *); <cstdio> /* remember: these actually are declared as f*64(), * while the original ones are undeclared. */ #undef fgetpos #undef fopen #undef freopen #undef fsetpos namespace std { using ::fpos_t; using ::fgetpos; using ::fopen; using ::freopen; using ::fsetpos; } I'm unsure how to 'fix' that 'correctly' - one suggestion is to 'fixincludes': Add this just _before_ those '#define fopen fopen64' lines in <stdio.h> static FILE *fopen(const char *a, const char *b) { return fopen64(a,b); } Eventually there is a better way to redirect from 'fopen' to 'fopen64' on aix also for the compiler - not just the preprocessor.
Created attachment 14796 [details] the effect fixincludes could have on aix5.2/aix5.3 When applying this patch to (already fixed) stdio.h on aix5.2/aix5.3, compiling "#include <iostream>" with -D_LARGE_FILES works. But I have no clue on how to create entries with this effect in inclhack.def, or if this is the way to go.
The test program will compile if you comment out the #undefs in cstdio. //#undef fgetpos //#undef fopen //#undef freopen //#undef fsetpos I've wrestled with this problem with G++ on AIX for years. In desparation I just had our admin load the IBM 4.0.0 RPMs - same problem! This is the second time this error has prevented me from porting a relatively simple application to AIX. This particular problem has gone on long enough.
Note that my originally stated workaround -- to compile with -maix64 -- doesn't really work beyond helping the compile to succeed. Using -maix64 gives you a 64-bit executable (e.g. with 64-bit pointers and a 64-bit off_t) that can't access large files.
The issue is whether to default G++ to _LARGE_FILES, as is done for Fortran, and perform all libstdc++ I/O as 64-bit operations, which will affect performance. Not everyone may want or need large I/O. There is no way to give users control over this without imposing it so G++, G++ headers, and libstdc++ all are self-consistent. The other alternative is another multilib, but there alredy are too many variants.
(In reply to comment #8) > The issue is whether to default G++ to _LARGE_FILES, as is done for Fortran, > and perform all libstdc++ I/O as 64-bit operations, which will affect > performance. Not everyone may want or need large I/O. There is no way to give > users control over this without imposing it so G++, G++ headers, and libstdc++ > all are self-consistent. The other alternative is another multilib, but there > alredy are too many variants. Why is this? -D_LARGE_FILES simply enables LFS. xlC works with and without -D_LARGE_FILES. Shouldn't G++ work as effectively as xlC?
Subject: Re: AIX g++ -D_LARGE_FILES fails to compile #include <iostream> > Why is this? -D_LARGE_FILES simply enables LFS. xlC works with and without > -D_LARGE_FILES. Shouldn't G++ work as effectively as xlC? You are mixing multiple questions and issues. -D_LARGE_FILES redefines all I/O functions to use the 64-bit versions. xlC has its own system header files. G++ needs to use the AIX system header files with changes from fixincludes, combined with libstdc++ header files that perform their own redefinitions. "Shouldn't G++ work as effectively..." is a business question, not a technical question. Many major AIX customers use GCC, but none have told IBM that they will not buy a system unless GCC works better. That sets investment priorities.
(In reply to comment #10) > Subject: Re: AIX g++ -D_LARGE_FILES fails to compile #include <iostream> > > xlC has its own system header files. G++ needs to use the AIX > system header files with changes from fixincludes, combined with libstdc++ > header files that perform their own redefinitions. Agreed. So, all that's left is for someone to do the work. I forgot about the libstdc++ headers that would need to change. We're going to try and have someone here work on this in the next 1-2 months as we're getting bitten by this.
If AIX G++ users are focussing on 64-bit apps and large files, I'm willing to switch the default to _LARGE_FILES. The changes would be in gcc/config/rs6000/aix*.h CPP_SPEC and libstdc++/config/os/aix/os_defines.h, plus any fallout from the change.
(In reply to comment #12) > If AIX G++ users are focussing on 64-bit apps and large files, I'm willing to > switch the default to _LARGE_FILES. The changes would be in > gcc/config/rs6000/aix*.h CPP_SPEC and libstdc++/config/os/aix/os_defines.h, > plus any fallout from the change. We only care about -D_LARGE_FILES to support files >2G while running a 32-bit app. We're not building any 64-bit apps.
(In reply to comment #12) I don't see it as so much a matter of "focus". A lot of applications test for _LARGE_FILES in the C library and will set it as a configuration option if supported. As far as straight C goes, there's no problem with gcc on AIX. But if _LARGE_FILES is set, the fact that g++ can't compile C++ applications using cstdio on AIX is a source of both frustration and annoyance. Does G++ really have to be either one way or the other? Can't it also include conditional code to check for _LARGE_FILES? Maybe I'm missing something here.
Subject: Re: AIX g++ -D_LARGE_FILES fails to compile #include <iostream> >>>>> tcoleman at autowares dot com writes: Tom> Does G++ really have to be either one way or the other? Can't it also include Tom> conditional code to check for _LARGE_FILES? Maybe I'm missing something here. GNU libc does not use _LARGE_FILE to distinguish large offsets in 32-bit file I/O. Why would the GCC libstdc++ community be interested in complicating its header files with AIX-specific checks?
(In reply to comment #15) > GNU libc does not use _LARGE_FILE to distinguish large offsets in > 32-bit file I/O. Why would the GCC libstdc++ community be interested in > complicating its header files with AIX-specific checks? I went back through the ChangeLog to find out where these #undef came from and why. http://gcc.gnu.org/ml/gcc-patches/2001-02/msg00275.html http://gcc.gnu.org/ml/gcc-patches/2000-11/msg00073.html http://gcc.gnu.org/ml/libstdc++/2000-11/msg00041.html It looks to me like while the undefs were at first added little by little to solve problems as they arose, they were eventually simply added en-mass without any particular bug being solved. This was also a problem on solaris: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4850 but it was "fixed" with the introduction of #pragma redefine_extname: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4850 Because it is not currently possible to build an autoconf based project on aix with gcc without doing --disable-largefile, we would like to see this fixed. How about something like: #if defined(fopen) && fopen != fopen64 #undef fopen #endif for all of: fseeko fseeko64 ftello ftello64 fgetpos fgetpos64 fsetpos fsetpos64 fopen fopen64 freopen freopen64 in libstdc++'s cstdio. If something like this is acceptable to David, we will try it on aix and linux and submit to -patches.
(In reply to comment #16) > This was also a problem on solaris: > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4850 I mean http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4886
(In reply to comment #16) > Because it is not currently possible to build an autoconf based project on aix > with gcc without doing --disable-largefile, we would like to see this fixed. More accurately, it is possible to use `gcc' and large files, just not `g++' and large files.
Proposed patch: http://gcc.gnu.org/ml/gcc-patches/2008-03/msg00162.html
Subject: Bug 20366 Author: rwild Date: Fri Mar 7 06:53:59 2008 New Revision: 133001 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=133001 Log: fixincludes/ 2008-03-07 Peter O'Gorman <pogma@thewrittenword.com> PR c++/20366 * inclhack.def (AAB_aix_stdio): Hack stdio.h for -D_LARGE_FILES. * fixincl.x: Regenerate. * tests/base/stdio.h: Add test. gcc/testsuite/ 2008-03-07 Peter O'Gorman <pogma@thewrittenword.com> PR c++/20366 * g++.dg/other/pr20366.C: New test. Added: trunk/gcc/testsuite/g++.dg/other/pr20366.C Modified: trunk/fixincludes/ChangeLog trunk/fixincludes/fixincl.x trunk/fixincludes/inclhack.def trunk/fixincludes/tests/base/stdio.h trunk/gcc/testsuite/ChangeLog
Fixed since 4.4.0