I have an issue in this code - which can be copied 1:1 into a cpp file in order to test the behaving:
#include <atomic>
typedef struct
{
char sDateTime [20];
char sLogFileDirectory [300];
char sLogFileNameTemplate [300];
char sLogOutput [10][100];
std::atomic<bool> bReadyToFlush;
} LogEntries;
typedef struct
{
LogEntries leLogEntries [1] {};
} LogThreads;
Compiling with gcc 4.9.2 SLES 11 SP2 g++ -std=c++11 gcc-warning-bug.cpp -Wall -Wextra -c I receive these very strange warnings:
gcc-warning-bug.cpp:18:34: warning: missing initializer for member ‘LogEntries::sDateTime’ [-Wmissing-field-initializers]
LogEntries leLogEntries [1] {};
^
gcc-warning-bug.cpp:18:34: warning: missing initializer for member ‘LogEntries::sLogFileDirectory’ [-Wmissing-field-initializers]
gcc-warning-bug.cpp:18:34: warning: missing initializer for member ‘LogEntries::sLogFileNameTemplate’ [-Wmissing-field-initializers]
gcc-warning-bug.cpp:18:34: warning: missing initializer for member ‘LogEntries::sLogOutput’ [-Wmissing-field-initializers]
gcc-warning-bug.cpp:18:34: warning: missing initializer for member ‘LogEntries::bReadyToFlush’ [-Wmissing-field-initializers]
Adding the {} initializer in this line
std::atomic<bool> bReadyToFlush {};
even g++ is complaining in the 1st warning about LogEntries::sDateTime then the warnings are gone.
The warning is also gone when I remove the std::atomic<bool> line. The code is very simple; when you have g++ 4.9.2 check it out - it is really very strange.
EDIT: Regardless to which LogEntries struct member I add the {} initializer the warnings are gone.
How can be this behaving explained? For me it is a bug...
PS:
I consider it as a bug:
Change the array specifier in this line to 1000:
LogEntries leLogEntries [1000] {};
g++ will produce 5'000 warnings! I would suppose that it does not really make sense to repeat the warning for each array value.
UPDATE:
The 1st case is now confirmed by GNU it is a bug but already fixed in gcc 5.0
The ICE [Internal Compiler Error] is now in the bug database GNU bug database
It seems to be a bug. I was now playing a bit around and I get after a modification the compiler message gcc stopped because of an internal error.
UPDATE: As requested the code which cannot be compiled by gcc. Compiler options: g++ -std=c++11 gcc-warning-bug.cpp -Wall -Wextra -Werror -fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations -c - some options are there because GNU requests it for a bug report.
#include <atomic>
class LogEntries
{
public:
char sDateTime [20];
std::atomic<bool> bReadyToFlush;
};
class LogThreads
{
public:
static LogEntries leLogEntries [10];
};
LogEntries LogThreads::leLogEntries [10] {};
Compiler fails with this output:
gcc-warning-bug.cpp:16:43: internal compiler error: in gimplify_init_constructor, at gimplify.c:4007
....
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
I will prepare the sample code and submit it to the developer team. In my project the member leLogEntries is static.
When you remove the std::atomic line then it works --> problem in the std::atomic implementation?
Related
Clang 8.0.0 and GCC 9.1.0 seem to disagree as to whether this is valid code.
struct Foo {
Foo([[maybe_unused]] int x) {}
};
int main() {}
Clang produces no warnings (even with -Wall -Wextra -Wpedantic) but GCC produces this error:
test.cpp:2:7: error: expected unqualified-id before '[' token
2 | Foo([[maybe_unused]] int x) {}
| ^
test.cpp:2:7: error: expected ')' before '[' token
2 | Foo([[maybe_unused]] int x) {}
| ~^
| )
So which compiler has a bug?
Yes, they can be applied. The standard allows this.
10.6.6 Maybe unused attribute [dcl.attr.unused]
...
2 The attribute may be applied to the declaration of a class, a typedef-name, a variable, a non-static data member, a function, an enumeration, or an enumerator.
So Clang is correct here and this is a GCC bug.
A bug report has already been filed for this titled: maybe_unused attribute triggers syntax error when used on first argument to a constructor
Your code is valid
The [[maybe_unused]] attribute can be applied to the declaration of a struct, enum, union,
typedef, variable (including member variables), function, or enumerator. Implementations are
encouraged to not emit a diagnostic when such an entity is unused or when the entity is used despite
being marked as [[maybe_unused]].
However there is already a bug report for this in gcc maybe_unused attribute triggers syntax error when used on first argument to a constructor . gcc probably is not able to parse it correctly.
This is likely an issue in your GCC compile line.
I receive a similar error when running the following line:
gcc *.cpp -o run_me
However, no issue is given when using the following line:
gcc -std=c++17 *.cpp -o run_me -Wall -Wextra -Wpedantic
Running with standard c++11 will give the warning "use of the 'maybe_unused' attribute is a C++17 extension". Be sure to use c++17 when compiling this code.
This is a simple program which i wrote it with vim editor:
#include <iostream>
using namespace std;
int main()
{
int a;
int b, c ;
a=(b+c+11)/3;
cout << "x=" << a;
cout << "\n";
return 0;
}
We can see the warnings in visual studio in windows:
...error(s), 2 warning(s)
...\test1.cpp(7) : warning c4700: local variable 'b' used without having been initialized
...\test1.cpp(7) : warning c4700: local variable 'c' used without having been initialized
But, When we use gnome-terminal, we can't see warnings:
SSS#SSS:~/.cpp$ g++ test1.cpp -o test1
SSS#SSS:~/.cpp$ chmod +x test1
SSS#SSS:~/.cpp$ ./test1
x=10925
SSS#SSS:~/.cpp$
In terminal we just can see errors...
How to see these warnings?
Any command?to see warnings?
Visual studio default warnings level is different from g++ default warning level.
You need to enable the warnings (I suggest -Wall) to see them.
g++ -Wall test1.cpp -o test1
prints:
test1.cpp: In function 'int main()':
test1.cpp:8:9: warning: 'b' is used uninitialized in this function [-Wuninitialized]
a=(b+c+11)/3;
~^~
test1.cpp:8:9: warning: 'c' is used uninitialized in this function [-Wuninitialized]
as the message suggests -Wuninitialized is enough for this kind of warnings, but I suggest you use -Wall for starters, and turn off the warnings that you don't need if you really need that on some legacy code, the best way being to enable extra warnings, and turn the warnings into errors so people have to fix them:
g++ -Wall -Wextra -Werror ...
Also note that you cannot rely on this warning to detect all uninitialized variables. There are complex cases where the compiler cannot decide if it's initialized (see why am I not getting an "used uninitialized" warning from gcc in this trivial example?). For that you need a more specialized tool like Valgrind.
I have a strange behavior of g++ that it shows a warning about unrecognized command line option, when any other warning is shown.
Example:
struct Foo{virtual int bar() = 0;};
struct Bar:public Foo{int bar() {return 0;} };
int main(){}
Compiling with g++-5 -Wsuggest-override -Wno-c99-extensions -std=c++11 a.cpp or even g++-5 -Wsuggest-override -Wno-c99-extensions a.cpp shows:
a.cpp:2:27: warning: ‘virtual int Bar::bar()’ can be marked override [-Wsuggest-override]
struct Bar:public Foo{int bar() {return 0;} };
^
cc1plus: warning: unrecognized command line option ‘-Wno-c99-extensions’
ADDITION: There is no warning/error when I compile with g++-5 -Wno-c99-extensions a.cpp hence that option passes CMAKEs check using CHECK_CXX_COMPILER_FLAG
This bothers me quite a lot, as we use Werror but with exceptions via Wno-error=... It then bails out when any of the (non-error) warnings is shown with the "unrecognized command line option"
Is this known/expected? How can it be prevented?
If you don't want warnings about unrecognised command-line options, don't use unrecognised command-line options: -Wno-c99-extensions has never been a valid GCC option (I believe it's a clangism). Simply remove it from your build command.
As for why the warning is only emitted when you have another warning present, this behaviour seems counter-intuitive but it is actually deliberate and documented:
The warning "unrecognized command-line option" is not given for -Wno-foo
Since GCC 4.4, and as explained in the GCC manual: when an unrecognized warning option is requested (-Wunknown-warning), GCC emits a diagnostic stating that the option is not recognized. However, if the -Wno- form is used, the behavior is slightly different: no diagnostic is produced for -Wno-unknown-warning unless other diagnostics are being produced. This allows the use of new -Wno- options with old compilers, but if something goes wrong, the compiler warns that an unrecognized option is present. (See PR28322 for the history of this change)
This might break configure tests that check for -Wno-foo options. The solution is to either test for the positive form (-Wfoo) or test using a testcase that triggers some other warning.
There are in fact a few results on Google of mailing list threads where software developers have faced this "problem", specifically with CMake, and made trivial fixes to their build scripts to "fix" it.
I've compiled a small program that uses asl_log, and when running in lldb, it failed to print the contents of a global variable from type 'aslclient', although i compiled in debug mode ('-g' flag).
perhaps you can tell me if this is related to the following bug, and how to workaround this problem
[lldb-dev] [Bug 16191] New: LLDB fails to evaluate expressions that
dereference a struct when inferior is built with recent Clang
the input from debugger :
(lldb) print log_asl_client
(aslclient) $5 = 0x0000000100200000
(lldb) print *log_asl_client
(lldb) print *log_asl_client
error: incomplete type '__asl_object_s' where a complete type is required
note: forward declaration of '__asl_object_s'
error: 1 errors parsing expression
my compilation command :
clang -g -c -Wall -DDEBUG=1 example.c -o example.o
clang example.o -o example
the code :
aslclient log_asl_client;
...
int main(int argc, char * const *argv) {
...
log_asl_client = asl_open(identity, facility, client_opts);
...
--> at this point i initiate the print command in debug mode.
the version i use :
clang --version
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix
thanks,
The debug information has a record for the forward reference to __asl_object_s, but not for the full type. This isn't entirely surprising in this particular case, since the only appearance of __asl_object_s in the public header files on OS X is:
typedef struct __asl_object_s *asl_object_t;
so this is an opaque reference to the struct, and there isn't a real definition anywhere. Presumably __asl_object_s is a placeholder and the pointer gets cast to whatever it really is when it is used.
Anyway, the debugger isn't refusing to show you something, there's actually nothing there to see...
I'm using Xcode 6.2 to build a C++ command line application.
The Xcode Build Setting Reference states:
If you develop products using C++, you may need to customize these build settings in your targets:
GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS (Effective C++ Violation)
However this option does not appear in the build setting list for any of my targets.
Can anyone tell me where it is?
The setting in question no longer has any effect - if you place it into the pbxproj file, it appears as a user defined setting in the UI.
The setting only applies to the gnu g++ compiler, and xcode doesn't ship with that compiler any more (it ships with clang++ and a g++ wrapper that invokes clang++). a brief test of some conditions that trigger with g++ doesn't trigger with clang++ e.g.:
#include <string>
using std::string;
class foo {
string x;
int y;
void *ptr;
public:
foo() : y(1), ptr(0) {}
};
$ g++-4.9 -c -Weffc++ evil.cpp
evil.cpp:5:7: warning: 'class foo' has pointer data members [-Weffc++]
class foo {
^
evil.cpp:5:7: warning: but does not override 'foo(const foo&)' [-Weffc++]
evil.cpp:5:7: warning: or 'operator=(const foo&)' [-Weffc++]
evil.cpp: In constructor 'foo::foo()':
evil.cpp:11:5: warning: 'foo::x' should be initialized in the member initialization list [-Weffc++]
foo() : y(1), ptr(0) {}
^
$ clang++ -c -Weffc++ evil.cpp
$
There are opinions that it is too noisy to be useful - e.g. the complaint about not initializing x (a std::string) is a pointless warning in this situation, and as such is more trouble than it's worth.
You can manually add the -Weffc++ option to the compilation flags for C++ code, you can add it to the option Other C++ Flags, which is under Apple LLVM X.Y - Custom Compiler Flags (the X.Y depends on your version of XCode), but again the LLVM based compiler doesn't process that option.
It looks like the documentation is out of date for this option - I've logged a radar to have the option removed from the docs to prevent this confusion.