Printing contents of a vector using auto variable - c++

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

Related

Warning: range-based for loop is a C++11 extension

While trying to compile a simple range based for loop on MacOS Big Sur, I got this warning:
warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
I tried using clang++ and g++ but both gave the same warning. Is there a way to always compile with C++11 without having to use -std=c++11 and without using aliases?
Edit: The reason I would prefer not to use -std=c++11 is because I want the compiler to default to C++11 or higher.
To provide this question with a proper answer, based on the discussion in the comments:
Compilers such as GCC and Clang set the default in their source code and it cannot be changed by, e.g., modifying a config file. The only way to change the default would be to change it in the source code and to compile the compiler yourself. This is not worth it.
Furthermore, compilers change their default language from time to time, and setting another default, e.g. to C++11, will make all non-C++11 code require setting the language version explicitly.
Here's the key point: code and compilation options belong together. Do not rely on compiler defaults. Any serious project will use a build system (e.g. Make) which specifies how to compile the project.
Edit
For completeness sake, the default C++ version for GCC 10.2.0 is hardcoded in /gcc/c-family/c-opts.c:
/* Set C++ standard to C++17 if not specified on the command line. */
if (c_dialect_cxx ())
set_std_cxx17 (/*ISO*/false);

I'm getting an error when I use size(vec) to find size of a vector instead of vec.size(). How to fix this?

The error that is being generated is below.
error: 'size' was not declared in this scope
When I use nums.size(), it is working fine. It could be because of using an older compiler version, but in my system when I check the version it shows 10.3.0, which I think is the latest version. How do I fix this?
The std::size function was added in C++17, therefore, you need to enable its support. With GCC, just add -std=c++17 as a command-line argument to your g++ call.
You can also check the libstdc++ source code: https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/range_access.h#L236. As you can see, there is an #ifdef that makes std::size available only if C++17 (or higher standard) support is applied.

Is this the correct way to initialize a vector in CPP?

I am running the below program on Dev-C++, and I am not able to execute it, as it always give me error while compiling the program.
#include<bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v2{2,3,4,5};
for(int x : v2)
{
cout<<x<<" ";
}
return 0;
}
[Warning] extended initializer lists only available with -std=c++11 or
-std=gnu++11
It always give me error, I just wanted to confirm, whether this type of Vector Initialisation is right? Or I am doing it the wrong way?
I am new to the community, sorry If this has been answered previously also, you could redirect me to the previous answer also.
Avoid use of <bits/stdc++.h>. It is not supported by some compilers and IDEs, plus it includes the entire STL library, which is unnecessary.
Instead, use specific templates such as <vector> in your case, since your using an std::vector. Don't forget to include <iostream> for std::cout as well.
[Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11
Provided your compiler supports C++ uptil a specific standard, you can set the standard using -std=standard, where 'standard' can be c++11, c++14, c++17 or c++20, taking into account of the recent versions of the C++ standard.
Your compiler clearly supports c++11 (in fact every compiler nowadays does, thats like the minimum) so just include that while compiling:
g++ -std=c++11 Filename.cpp -o Filename
This will compile your C++ file using g++ compiler with C++11 standard, and create an object file of the source file 'Filename.cpp'.

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.

clang produces warning regarding c++11 despite update

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.