Can't find Xcode build setting - GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS - c++

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.

Related

Can attributes be applied to constructor parameters?

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.

cc1plus: unrecognized command line option warning on any other warning

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.

lldb debugger cannot print structure contents

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...

gcc 4.9.2 bug in -Wmissing-field-initializers?

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?

Where is definition of std::function in clang++ (3.3/Xcode)

Problem Solved => see the update at the end
I'm trying to use std::function but it looks like just include <functional> does not provide the definition. I have tried to compile following code:
#include <functional>
std::function<int(int)> f = nullptr;
with c++11 as compile option:
% clang++ -c -std=c++11 t.cc
cause:
t.cc:3:6: error: no type named 'function' in namespace 'std'
std::function<int(int)> f = nullptr;
~~~~~^
t.cc:3:14: error: expected unqualified-id
std::function<int(int)> f = nullptr;
^
2 errors generated.
what am I missing? I know C++ well but new to clang++/C++11 thus I lack of important knowledge, I guess.
I'm using clang++ on MacOS X 10.8.
Update 1
I have tried a sample at cppreference.com site but it won't compile too. Giving some option solve the problem?
Update 2
Tried above sample from cppreference.com with clang++ -c -std=c++11 -stdlib=libc++11 x.cc, and compiler still says:
x.cc:1:10: fatal error: 'functional' file not found
#include <functional>
^
1 error generated.
Where is functional? I guess I should give -stdlib=libc++11 or whatever but it does not work too:
clang: error: invalid library name in argument '-stdlib=libc++11'
How I can find list of argument for -stdlib? (note: in man page, only available options are libc++ and libstdc++ both of them don't work)
Or functional just does not work?
This is not about the definition of the function. You don't have a linker error. You have a compiler error. The problem is, presumably, that the BSD/GNU/Darwin standard library installed in the real sysroot doesn't support C++11. You have to use the one that comes with Clang by specifying the -stdlib=libc++ compiler flag.
For C++11, it's best to always invoke clang as: clang++ -std=c++11 -stdlib=libc++
I use this most of the time, so I set the environment variable $CXX to this value. That way, I'm getting the dialect and library option in both compilation and linking. -std=c++11 is insufficient, as clang will still use the (old) system gcc headers in /usr/include/c++/4.2.1.
-stdlib=libc++ will use the clang headers in /usr/lib/c++/v1 such as <functional>.
There's a similar question with an answer by Howard Hinnant, who is (IIRC) an Apple engineer.