Follow up to my answer to this question: SIGSEGV on declaration
In this question the questioner had a problem with a segmentation fault on some simple code. As it turned out it didn't even compile for me and others. GCC (4.8.1) gave an error due to redeclaration of a variable with name bsearch, which happens to be identical to a function name in std. This resulted in a clash as the code also used using namespace std;. Since the questioner accepted my answer I guess this was somehow related with the runtime error (though strange).
The questioner however said the code would compile fine on codeblocks and others confirmed this. bsearch should be defined in cstdlib, but the code did not include it.
It turned out that gcc includes cstdlib if iostream is included anyway as one can see from the trace:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++0x -Wall -Wextra -pedantic -MMD -MP -MF"src/Test.d" -MT"src/Test.d" -o "src/Test.o" "../src/Test.cpp"
../src/Test.cpp:14:27: error: ‘long long int bsearch’ redeclared as different kind of symbol
long long int bsiter,bsearch;
^
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/cstdlib:72:0,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/ext/string_conversions.h:41,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/basic_string.h:2815,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/string:52,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/locale_classes.h:40,
src/subdir.mk:18: recipe for target 'src/Test.o' failed
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/ios_base.h:41,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/ios:42,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/ostream:38,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/iostream:39,
from ../src/Test.cpp:1:
/usr/include/stdlib.h:754:14: error: previous declaration of ‘void* bsearch(const void*, const void*, size_t, size_t, __compar_fn_t)’
extern void *bsearch (const void *__key, const void *__base,
^
make: *** [src/Test.o] Error 1
It does so only in c++0x and c++11 mode.
Is this structure of includes required, allowed or defined at all in the c++ standards? On cplusplus.com I can find that iostream will include ostream and ios, but there is no information about includes further down.
The C++ standard mandates in certain places that another header has to be included (e.g., <iostream> has to include <istream> and <ostream>). Otherwise, the standard allows headers to be included and to make declaration available which are not required to become available from a specific header.
I'd think it would be useful to have a system of headers which make exactly those declarations available that are required to be made available but I'm not aware of that being available. These headers could be without actual definitions and would only be used to verify that all necessary headers are included. It might be better to have the headers be part of an actual implementation but that would make the declarations quite a bit more complex.
Related
I'm writing a C++ application which uses a C library that defines a tail-padded structure in one of its headers. Without going into too much details, it looks somewhat like this:
struct MyStruct {
// ... other members
// The last member, a tail-padding array
MyType myBuffer[];
}
I use -Wall -Wextra -Wpedantic -Werror with g++ and -std=c++0x.
Unfortunately, g++ gives me a warning about that array:
error: ISO C++ forbids zero-size array 'myBuffer' [-Wpedantic]
What is the right way to deal with this?
I know I can suppress the warning by adding a pragma to the header myself:
#pragma GCC diagnostic ignored "-Wpedantic"
But that doesn't feel right. What do you guys suggest?
You could
Remove the zero-sized array.
Build without -Wpedantic (possibly only for that file).
Build without -Werror and ignore the warning.
Build the code as C.
I'm using compile flags -Wall -Wextra and -Werror. I'm getting a flood of "declared ‘static’ but never defined [-Werror=unused-function] " Warnings (treated as errors) when I compile the following file. No such warnings when I reverse the order of the #include directives. Please help me understand why?
I know I could remove the extra warnings and errors and get my program to compile, clearly that's not my intent or my code would be more interesting. I'm trying to gain a deeper knowledge of C++, and improve my habits through cleaning up warnings in my code.
I understand that argp is really a C library, and iostream is a C++ library, perhaps that's part of the issue. I'd be happy to use a proper C++ library to accomplish what argp does, but I can't find one. If there is one I'd be happy to hear about it.
#include <argp.h>
#include <iostream>
int main(int argc, char **argv)
{
return 0;
}
To be clear, I am working on a non-trivial program, and have specific reasons for wanting to use C++ instead of C. I've boiled down the code shown here to the least possible code to produce the effect I'm trying to understand. Please don't suggest that I don't need one or the other of the headers.
Compiler: gcc
:~/scratch/argp_example$ gcc --version
gcc (Ubuntu 5.2.1-23ubuntu1~12.04) 5.2.1 20151031 Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
compiler invokation:
g++ -o obj/main.o -c src/main.cpp -Wall -Wextra -Werror -pedantic -MMD --std=c++11 -Iinc
Specific compiler feedback:
In file included from /usr/include/x86_64-linux-gnu/c++/5/bits/gthr.h:148:0,
from /usr/include/c++/5/ext/atomicity.h:35,
from /usr/include/c++/5/bits/ios_base.h:39,
from /usr/include/c++/5/ios:42,
from /usr/include/c++/5/ostream:38,
from /usr/include/c++/5/iostream:39,
from src/main.cpp:2:
/usr/include/x86_64-linux-gnu/c++/5/bits/gthr-default.h:101:1: warning: ‘int __gthrw_pthread_once(pthread_once_t*, void (*)())’ declared ‘static’ but never defined [-Wunused-function] __gthrw(pthread_once) ^
There are many many more similar errors from gthr.h. This specific copy/paste was from a run without -Werror, but that's the only difference.
SOLUTION:
This was my choice of solution, but of course, you could simply reverse the order of includes. It is a recognized bug, so there is no "correct" answer, all solutions would be workarounds. This one, I think, is least likely to give me or others fits later.
#include <argp.h>
#undef __attributes__
#include <iostream>
...
This is a known bug. The culprit is this chunk of code in argp.h, which is triggered when you use -std=c++xx:
#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
# define __attribute__(Spec) /* empty */
# endif
The declarations at issue are normally marked with __attribute__ ((__weakref__("pthread_meow"))), but this macro caused that attribute to vaporize.
Until the bug gets fixed, you might want to compile with -std=gnu++xx, or manually #undef __attribute__ after including argp.h.
I have 2 separate working projects on a raspberry running raspbian. i am having some problems when joining them together and as i am not that good with the compiler itself(still learning) i don't know how to work it out.
Error (finish_with_error can be ignored):
In file included from main.c:20:0:
/usr/local/include/wiringPi.h:216:21: error: conflicting types for ‘bcm2835_delayMicroseconds’
bcm2835.h:912:17: note: previous declaration of ‘bcm2835_delayMicroseconds’ was here
main.c:200:6: warning: conflicting types for ‘finish_with_error’ [enabled by default]
main.c:124:33: note: previous implicit declaration of ‘finish_with_error’ was here
The command i am using to compile is:
gcc config.c rfid.c rc522.c main.c -o rc522_reader -lbcm2835 -lwiringPi -lwiringPiDev `mysql_config --cflags --libs`
Bcm2835.h(line 912):
extern void bcm2835_delayMicroseconds (uint64_t micros);
wiringPi.h(line 216):
extern void delayMicroseconds (unsigned int howLong) ;
The problem is that i cant see where i there is two declarations the same way, these are libraries so i would prefer not to modify to avoid malfunctioning on the libs, is there something i can do to tell the compiler what to do?
Thanks,
I'm working on an existing C++ codebase that happens to use SIZE_MAX in a couple of places. I did some refactoring and now SIZE_MAX is not defined in one of the modules. This problem appeared when Travis-CI attempted to build the project on Linux. It worked fine before I refactored stuff, but tracing which exact header files were included is difficult.
In an attempt to replicate the problem locally, I installed an Ubuntu VM with the default gcc and was able to reproduce it. Here's the relevant source:
#include <stddef.h>
int main()
{
size_t a = SIZE_MAX;
}
The command line is simply:
g++ a.cpp
The error is:
a.cpp: In function ‘int main()’:
a.cpp:5:16: error: ‘SIZE_MAX’ was not declared in this scope
System info:
$ uname -a
Linux quartz 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:39:31 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
I have tried including cstdint, stdint.h, limits.h, inttypes.h, stdio.h, stdlib.h, and probably some others, and I can't figure out which specific header file I need for SIZE_MAX.
It is important to note that the program I'm working on compiled fine, with SIZE_MAX used in various places, before I made some changes. The changes I made caused it to become undefined in one .cpp source file where it was used (the others continue to be fine). So there exists some header file on my system where it is correctly defined.
It's likely that some header defined __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS before stdint.h was included.
Compiling on Linux with g++ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS a.cpp should fix this issue on the older compilers.
If you'd like to learn more about these macros...
18.4.1 Header <cstdint> synopsis
The header also defines numerous macros of the form:
INT_[FAST LEAST]{8 16 32 64}_MIN
[U]INT_[FAST LEAST]{8 16 32 64}_MAX
INT{MAX PTR}_MIN
[U]INT{MAX PTR}_MAX
{PTRDIFF SIG_ATOMIC WCHAR WINT}{_MAX _MIN}
SIZE_MAX
EDIT
In the current C++11/14 standard, SIZE_MAX is introduced and mentioned only in <cstdint>. It is also part of C99, of which specification C++11 fully includes via the <cxxx> headers. So it seems it was not defined prior to C++11.
Which C++ standard header defines SIZE_MAX?
Its supposed to be defined in <cstdint>, but its optional.
Here are the results on Fedora 22 with GCC 5.1:
#include <cstdint>
// use SIZE_MAX
Results in:
g++ -DNDEBUG -g -O2 -fPIC -march=native -pipe -c filters.cpp
In file included from /usr/include/c++/5.1.1/cstdint:35:0,
from filters.cpp:14:
/usr/include/c++/5.1.1/bits/c++0x_warning.h:32:2: error: #error This file requires
compiler and library support for the ISO C++ 2011 standard. This support is currently
experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support for the \
^
filters.cpp: In constructor ‘Filter::Filter(BufferedTransformation*)’:
filters.cpp:305:36: error: ‘SIZE_MAX’ was not declared in this scope
: Filter(attachment), m_firstSize(SIZE_MAX), m_blockSize(0), m_lastSize(SIZE_M
^
It was simply easier to do the following, and stop worrying about non-portable optional-ness that still causes problems in 2015.
#include <limits>
#ifndef SIZE_MAX
# ifdef __SIZE_MAX__
# define SIZE_MAX __SIZE_MAX__
# else
# define SIZE_MAX std::numeric_limits<size_t>::max()
# endif
#endif
Trying __SIZE_MAX__ gets you back to the compile time constant that you probably crave. You can see if its defined in the preprocessor with cpp -dM < /dev/null | grep __SIZE_MAX__.
(And how/why numeric_limits<size_t>::max() is not a compile time constant is another C++ mystery, but that's a different problem).
I am writing a Rcpp code that include two library RcppArmadillo and trng4. However, when I include two header files (RcppArmadillo.h and trng/gamma_dist.hpp) it gives compilation error.
trng/special_functions.hpp:47:39: error: declaration of ‘float lgammaf(float) throw ()’ has a different exception specifier
extern "C" float lgammaf(float) throw();
include-fixed/math.h:476:14: error: from previous declaration ‘float lgammaf(float)’
extern float lgammaf(float);
Full compilation options are
-fopenmp -lgomp -DUSE_R -DNDEBUG -DDISABLE_SINGLE -DNTHROW -DDISABLE_FIO -I/usr/local/include -I"/Users/avi/Library/R/3.0/library/Rcpp/include" -I"/Users/avi/Library/R/3.0/library/RcppArmadillo/include" -fPIC -pipe -std=c++0x -Wall -pedantic -c
Seems like the lgammaf is declared in both header files. I tried using -E with g++ option but that give ld warning " .o, file was built for unsupported file format" and give error function in not available in .Call when I try it to after loading in R. What am I doing wrong?
Perhaps out of context I am using trng4 package to develop a thread gibbs sampler (in openmp) that sample from gamma distribution. I am currently running this MacOS. But eventual it will run in linux server.
It sounds like you do have a problem between Armadillo and trng4. Maybe you should try to, if possible, separate your interface so that you do not need to include from both in the same file.
Someone can correct me if I'm wrong, but I believe you prevent this issue by using #ifndef in each header file so that it's not defined a second time even if it's included a second time. But I guess these aren't your files are they...?
#ifndef __your_unique_header_name__
blah blah
#endif