clang produces warning regarding c++11 despite update - c++

updated clang recently (as well as xcode and developer tools) and ran a simple program to see if it was supporting c++11. Look like this:
#include <iostream>
using namespace std;
int main()
{
string my_array[5] = {"one", "two", "three"};
for (string &x : my_array)
cout << x << endl;
}
compile in terminal like this:
clang++ -std=c++11 -stdlib=libc++ -Weverything main.cpp
and get this warning:
main.cpp:17:20: warning: range-based for loop is incompatible with C++98
[-Wc++98-compat]
for (string &x : my_array)
but it still produces an executable and runs as expected. Why is this error being produced?

This is a warning rather than an error. The warning message also indicates the warning flag that enables it: -Wc++98-compat. This flag is enabled because you've enabled -Weverything (a good idea, IMO). To disable a specific warning you pass a warning flag with 'no-' prefixed to the warning name you want to disable:
-Wno-c++98-compat
The purpose of this warning is to allow building code as C++11 and to gain some C++11 benefits, such as performance improvements from move semantics, while still producing code compatible with older compilers. That is, this warning doesn't indicate any kind of problem with the program and the program will work just as the C++11 spec indicates (other than clang bugs, of course), but the warning is to inform you that if you were to compile as C++98 then it would not work.
If you don't plan to build the code as C++98 then this warning doesn't have any value to you and you should simply disable it.
I believe there's also a -Wc++11-compat flag in the latest versions now that clang supports (what will probably be called) C++14.

Related

Using [[deprecated]] attribute when warnings are errors (-Werror)

I'm migrating to C++14 and keen to adopt its [[deprecated]] functionality, e.g.
#include <string>
#include <iostream>
[[deprecated]]
int f() { return 42; }
int main()
{
std::cout << f() << std::endl;
}
compiled with
g++ example.cpp -std=c++14 -Werror
and the problem is the deprecated warning is promoted (demoted?) to an error and the build fails.
Obviously using a #pragma to silence the warning completely defeats the point. Is there any way to tell g++ to emit warnings yet exclude specific ones from being treated as errors?
You need to add
-Wno-error=deprecated-declarations
to tell gcc to keep deprecated-declarations as a warning instead of making it an error.
You can add additional
-Wno-error=name_of_warning
if you have additional warnings that you would like to not be treated as errors as well.
With GCC (And also Clang) you can disable errors for specific warnings.
Using -Wno-error= followed by the name of the warning (displayed together with the warning or error) will disable the error for that specific item.
For your case with [[deprecated]], use the option -Wno-error=deprecated-declaration, and those will become warnings again instead of errors.

Printing contents of a vector using auto variable

I read in a book that a shorter way to iterate through a vector is as follows:
for (auto x : v)
{
cout << x << "\n";
}
When I tried the same out in my compiler I got two error messages stating:
'auto' changes meaning in C++11, please remove it range based 'for' loops only available in c++11" and " 'x' maybe used uninitialized in this function
Can someone please point out the error and the solution?
Your syntax is correct. Be mindful that you're taking a copy of every element in x though, you might want to use const auto& instead.
You need to enable C++11 in your compiler - if you're using gcc or clang, you can simply pass the -std=c++11 flag.
Are you sure you are compiling your code with a C++11 compiler?
With gcc you need the -std=c++11 flag:
g++ -std=c++11
Same for clang:
clang++ -std=c++11
The error is that you use language features that were introduced in the C++11 standard, while compiling with a compiler (in a mode) that doesn't support C++11.
Solution is to use a compiler (in a mode) that does supports C+++11. If your compiler supports C++11 (and it probably does, since it knows of the change of meaning of auto), then its documentation will specify how to enable C++11 or later standard mode.
What compiler are you using?
gcc (tdm 64-1) 5.1.0
The manual of your compiler says:
To select this standard in GCC, use the option -std=c++11; to obtain all the diagnostics required by the standard, you should also specify -pedantic

Is there a warning for string literal to bool conversion in gcc

In a quite large code base, I found the following construct (rewritten snippet) in a cpp file
int main()
{
bool b;
//... some code ...;
b = "False"
}
This is completely legal code, but clearly not intentional. It is easily fixed, but it has been present since 2014 without anyone noticing, so it is obviously not easy to spot.
Is it possible to make gcc warn about this?
Neither g++ 7 nor clang++ 5 warn with -Wall -Wextra -Wpedantic.
Clang has a warning called -Wstring-conversion that will catch the mistake, but gcc doesn't have it. I briefly looked through the gcc warning documentation page and didn't find anything that would catch the mistake.
live wandbox example
I've filed a report for a feature suggestion on the gcc bug tracker: #80151.

GCC vs Clang: Meaning of "-pedantic-errors"

I'm using Clang v3.7.0 with Mingw-w64 5.1.0 and GCC 5.1.0, all 64-bit, on Windows 10. My goal is to use a set of Clang and GCC options that will give me the best chance of detecting potential C89 and C++98 language standards portability issues across many different compilers. For example, for C I have been using the following GCC command line with pretty good success:
gcc -c -x c -std=c89 -pedantic-errors -Wall -Wextra -Wno-comment -Wno-parentheses -Wno-format-zero-length test.c
However, I recently tried it with Clang and got a different result. Here is my sample test code:
int main(void)
{
int length = (int)strlen("Hello");
return 0;
}
With Clang I get the following error, whereas with GCC I get the same basic thing, but it flags it as a warning instead:
test.c:3:22: error: implicitly declaring library function 'strlen'
with type 'unsigned long long (const char *)'
int length = (int)strlen("Hello");
If I remove the -pedantic-errors option, or just change it to -pedantic, Clang then only flags it as a warning, which is what I actually want. However, according to the GCC documentation the -pedantic-errors option causes warnings that are considered language extensions to be flagged as errors, but not using a prototype for a function is not an extension in C89. So, I have three basic questions:
Has Clang changed the meaning of -pedantic-errors from the meaning used by GCC, or am I misinterpreting something?
What is the best set of options that will enforce adherence to the selected standard and will issue errors for all non-conforming code?
If I continue to use -pedantic-errors with Clang is there a way to get it to issue a warning instead of an error in specific cases? In another posting on this site an answer was given that said to use the following, where foo is the error:
-Wno-error=foo
If that is a correct approach, what do I actually use in place of foo for an error like I'm getting since there is no actual error number indicated? I can't believe it actually wants all of the following:
-Wno-error=implicitly declaring library function 'strlen'
with type 'unsigned long long (const char *)'
Your code is invalid, and the behavior is undefined, so the compiler can do anything also when compiling. The implicitly declared int strlen(char*) is not compatible with size_t strlen(const char *).
Has Clang changed the meaning of -pedantic-errors from the meaning used by GCC, or am I misinterpreting something?
As I read it, yes. From clang documentation:
-pedantic-errors
Error on language extensions.
In GCC:
-pedantic
Issue all the warnings demanded by strict ISO C and ISO C++ [...]
-pedantic-errors
Give an error whenever the base standard (see -Wpedantic) requires a diagnostic, in some cases where there is undefined behavior at compile-time and in some other cases that do not prevent compilation of programs that are valid according to the standard.
Clang errors on extensions.
GCC errors when standard explicitly requires it and in other "some cases".
This is a different, it is a different set of errors. Standard may not require a diagnostic, but it's still an extension - GCC will be silent, Clang will error.
What is the best set of options that will enforce adherence to the selected standard and will issue errors for all non-conforming code?
The first answer that comes to mind is: "none". Compiler inherently use "implementation-defined behavior" and extension, because they are meant to compile the code in the first place, not meant to not compile non-conforming code. There are cases where the code is conforming, but still the behavior differs between compilers - you can explore such a case here.
Anyway, keep using -pedantic-errors, as it seems to work in detection of non-conforming code. Your code is invalid, the behavior is undefined, so your code is non-conforming, so clang properly detects it. Also use linters and sanitizers to detect other cases of undefined behavior.
If I continue to use -pedantic-errors with Clang is there a way to get it to issue a warning instead of an error in specific cases?
Use -fno-builtin.

(Di|Tri)graphs in C++11

After reading up on digraphs and trigraphs I went on and tested a simple program:
#include <stdio.h>
int main()
{
int a = 0;
//??/
++a;
printf("%d",a);
return 0;
}
and by reflex I did
g++ -std=c++11 test.c
and to my surprise no warnings were emitted and 0 was printed so I went on and tried compiling with the C compiler and it did emit a warning due to the trigraph.
My question is why does -std=c++11 automatically pull in -trigraphs and emit no warning by default ? (without using -Wall) Do implementations of certain C++11 features require them? (highly doubt it but worth asking)
Passing -std=c99 has the same effect of enabling the trigraph and disabling the warning.
It must enable the trigraph to be strictly standard-compliant. Disabling the warning is surprising, but note that the warning is about a trigraph being ignored. The warning probably goes away because -std failed to activate separate warnings (-Wtrigraphs) about a trigraph being used.
And that should probably be considered a bug.