Variable assignment inside a C++ 'if' statement - c++

In C++, the following is valid and I can run it without a problem:
int main(){
if (int i=5)
std::cout << i << std::endl;
return 0;
}
However, even though the following should also be valid, it gives me an error:
if ((int i=5) == 5)
std::cout << i << std::endl;
Error:
test.cpp: In function ‘int main()’:
test.cpp:4:10: error: expected primary-expression before ‘int’
if ((int i=5) == 5)
^
test.cpp:4:10: error: expected ‘)’ before ‘int’
test.cpp:5:36: error: expected ‘)’ before ‘;’ token
std::cout << i << std::endl;
^
Furthermore, in C++17 the below code must be valid too, but it gives me a similar error again:
if (int i=5; i == 5)
std::cout << i << std::endl;
Error:
test.cpp: In function ‘int main()’:
test.cpp:4:16: error: expected ‘)’ before ‘;’ token
if (int i=5; i == 5)
^
test.cpp:4:18: error: ‘i’ was not declared in this scope
if (int i=5; i == 5)
^
I am trying to compile with g++ test.cpp -std=c++17. g++ --version gives me g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609. What am I missing here?

if ((int i=5) == 5) is a syntax error. It does not match any supported syntax for if statements. The syntax is init-statement(optional) condition, where condition could either be an expression, or a declaration with initializer. You can read more detail about the syntax on cppreference.
if (int i=5; i == 5) is correct. However, you are using an old version of GCC that dates from before C++17 was standardized. You would need to upgrade your compiler version. According to C++ Standards Support in GCC this feature was added in GCC 7.

For starters, I believe your compiler is right to reject
if ((int i=5) == 5)
because this is not legal C++ code. A variable declaration statement isn’t an expression, so you can’t treat (int i = 5) as an expression.
For the second one, I suspect you just need to update your compiler. g++ 5.6 is a fairly old version at this point, and I believe more updates versions of g++ will handle that code with no problem.

Related

Using unordered_map on my g++ (5.1.0) compiler in command prompt shows error

I have recently downloaded MinGW into my computer but on using certain containers and iterators like unordered_map and auto it shows an unexpected error.
my code is as follows :
#include <bits/stdc++.h>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<string, int> umap;
umap["GeeksforGeeks"] = 10;
umap["Practice"] = 20;
umap["Contribute"] = 30;
for (auto x : umap)
cout << x.first << " " << x.second << endl;
return 0;
}
it gives the following error :
C:\Users\naima\Documents\cpp>g++ -o try2 try2.cpp
In file included from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/unordered_map:35:0,
from try2.cpp:2:
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/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 \
^
try2.cpp: In function 'int main()':
try2.cpp:9:5: error: 'unordered_map' was not declared in this scope
unordered_map<string, int> umap;
^
try2.cpp:9:25: error: expected primary-expression before ',' token
unordered_map<string, int> umap;
^
try2.cpp:9:27: error: expected primary-expression before 'int'
unordered_map<string, int> umap;
^
try2.cpp:11:5: error: 'umap' was not declared in this scope
umap["GeeksforGeeks"] = 10;
^
try2.cpp:15:15: error: 'x' does not name a type
for (auto x : umap)
^
try2.cpp:19:5: error: expected ';' before 'return'
return 0;
^
try2.cpp:19:5: error: expected primary-expression before 'return'
try2.cpp:19:5: error: expected ';' before 'return'
try2.cpp:19:5: error: expected primary-expression before 'return'
try2.cpp:19:5: error: expected ')' before 'return'
The compiler told you exactly what was wrong. It usually will.
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.
You just have to compile with the proper flag, -std=c++11. I don't know if you are version-matching against what graders use or what, but there are very few good reasons to be on a minGW compiler where support for an 8 year old standard is still considered experimental.
You can see that it works as expected here: https://godbolt.org/z/JQxL00
If you remove the -std=c++11 flag, it will fail to compile and give you the same error message.
You might also notice that I altered the includes to only include what I use. This results in a much faster compile time, smaller executable, and an easier to understand piece of code (Since it is plain to see what standard features are being used). You also avoid polluting your namespace.

Expression list treated as compound expression

I'm trying to compile a program I got from the net. Trying to use in codeblocks but its showing errors. I don't understand what is going wrong. I've looked up in various forums but not much light is shed. Can anyone help soon? Thanks in advance
#include <functional>
#include <iostream>
int print_num(int i, int j) { return i + j; }
int main() {
std::function<int(int, int)> foo = print_num;
std::function<int(int, int)> bar;
try {
std::cout << foo(10, 20) << '\n';
std::cout << bar(10, 20) << '\n';
} catch (std::bad_function_call& e) {
std::cout << "ERROR: Bad function call\n";
}
return 0;
}
These are some of the errors other than 14 other errors saying declaration not done. I guess clearing these error would solve that problem.
main.cpp|10|error: 'function' is not a member of 'std'
main.cpp|10|error: expression list treated as compound expression in functional cast [-fpermissive]
main.cpp|10|error: expected primary-expression before 'int'
You need to compile with -std=c++11 to add in the C++11 features.
$ g++ -std=c++11 test.cxx && ./a.out
30
ERROR: Bad function call
vs:
$ g++ test.cxx && ./a.out
test.cxx: In function ‘int main()’:
test.cxx:10:3: error: ‘function’ is not a member of ‘std’
test.cxx:10:28: error: expression list treated as compound expression in functional cast [-fpermissive]
test.cxx:10:17: error: expected primary-expression before ‘int’
...

C++ I'm expecting a narrowing conversion error but not getting it

In the following code from Stroustrup's book we are warned against an error from a narrowing conversion which does not occur on my version GCC (4.7.2)
#include <iostream>
using namespace std;
int main()
{
int i1 = 7.2;
int i2{7.2};
cout << i1 << " " << i2 << endl;
return 0;
}
As demonstrated here at ideone is this a bug or am I not running with the appropriate command line arguments to the compiler? Or is this meant to be a purely semantic error?
With g++ 4.8.1:
foo.cpp: In function 'int main()':
foo.cpp:8:15: warning: narrowing conversion of '7.2000000000000002e+0' from 'double' to 'int' inside { } [-Wnarrowing]
int i2{7.2};
^
I assume it's simply a bug in 4.7.2's c++11 support.
I get a narrowing warning with GCC 4.7.3 when I use -std=c++0x:
g++ -std=c++0x test.cpp
test.cpp: In function ‘int main()’:
test.cpp:8:23: warning: narrowing conversion of ‘7.2000000000000002e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
g++ --version
g++ (GCC) 4.7.3

#define causes an "expected primary-expression" error

#define N 10;
int main()
{
int x;
for (int i=0; i<N; i++)
x = i;
return 0;
}
Result of compiling this in g++:
test-define.cpp: In function ‘int main()’:
test-define.cpp:7:22: error: expected primary-expression before ‘;’ token
test-define.cpp:7:22: error: expected ‘)’ before ‘;’ token
test-define.cpp:7:24: error: name lookup of ‘i’ changed for ISO ‘for’ scoping [-fpermissive]
test-define.cpp:7:24: note: (if you use ‘-fpermissive’ G++ will accept your code)
test-define.cpp:7:27: error: expected ‘;’ before ‘)’ token
But it compiles fine when I change line 7 to for (int i=0; i<10; i++).
Why is this and how can I use the #define directive to accomplish what I want?
Remove the semicolon - you will be good - the semicolon is included in the substitution
Sometimes it is useful to get the compiler to run the preprocessor only. With gcc/g++ you can do something like
gcc -E file.c > result.txt
This will show you how the macro expanded (hint start at the end of the file and work up)
I recommend replacing the macro with a constant:
const int N = 10;
It's best to avoid macros when you can. Macros don't have any scope. They are a global text substitution. The compiler never sees them, so if you use a debugger it won't know about them. There are probably other reasons not to use them that I'm forgetting.

G++ doesn't compile C++0x range-based for loop

I was experimenting with some of the new C++0x features with G++. Lambdas, auto, and the other new features worked like a charm, but the range-based for-loop failed to compile. This is the program I was testing:
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> data = { 1, 2, 3, 4 };
for ( int datum : data )
{
std::cout << datum << std::endl;
}
}
I compiled it with:
g++ test.cpp -std=c++0x
I also tried gnu++0x, but the output was the same.
This was the output:
test.cpp: In function ‘int main()’:
test.cpp:8:21: error: expected initializer before ‘:’ token
test.cpp:12:1: error: expected primary-expression before ‘}’ token
test.cpp:12:1: error: expected ‘;’ before ‘}’ token
test.cpp:12:1: error: expected primary-expression before ‘}’ token
test.cpp:12:1: error: expected ‘)’ before ‘}’ token
test.cpp:12:1: error: expected primary-expression before ‘}’ token
test.cpp:12:1: error: expected ‘;’ before ‘}’ token
Thanks in advance for your help.
EDIT: I am using GCC version 4.5.2, which I now see is too old.
You need GCC 4.6 and above to get range-based for loops.
GCC's C++0x status
$ cat for.cpp
#include <iostream>
int main()
{
for (char c: "Hello, world!")
std::cout << c;
std::cout << std::endl;
return 0;
}
$ g++ -std=c++0x -o for for.cpp
$ ./for
Hello, world!
$ g++ --version
g++ (GCC) 4.6.1 20110325 (prerelease)