Why does const int change values - c++

Im starting to learn c++ and was under the impression that by putting const is means that the value wont change but i wrote the following code:
#include<iostream>
int main()
{
const int a = 1;
a += 1;
std::cout << a << std::endl;
return 0;
}
and it prints out 2 while i thought it would have given me an error for changing a const int value.
I am using MSVS as my compiler
EDIT: I get a compiler warning saying C4530: C++ exception handler used, but unwind semantics are not enabled, specify /EHsc
It works now and gives me the correct error but does anyone know what this means

This program cannot be compiled using GNU GCC 4.8:
alioth% g++ x.cpp
x.cpp: In function ‘int main()’:
x.cpp:6:7: error: assignment of read-only variable ‘a’
a += 1;
Either your compiler is broken or you are doing something wrong (like compiling different project).

This program cannot be compiled on VS2013:
1>------ Build started: Project: SOTesting, Configuration: Release Win32 ------
1> Source.cpp
1>Source.cpp(6): error C3892: 'a' : you cannot assign to a variable that is const
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========`

The posted code:
#include<iostream>
int main()
{
const int a = 1;
a += 1;
std::cout << a << std::endl;
return 0;
}
The claim that this code compiled and produced "2" as output, is incorrect.
You can easily get the impression of something like that by inadvertently compiling a different program, or not noticing that a compilation failed and then running an existing executable.

Related

List initialization returns semicolon error

I'm trying to compile the following C++ code on Visual Studio Code, using the Mac clang compiler.
#include <iostream>
int main() {
int x { 5 };
std::cout << x;
return 0;
}
However, this returns an error, on the line of the list initialization: int x{ 5 };. Specifically, it says I need to insert a semicolon after the x.
I don't get what's wrong with this code, it works fine on an online compiler. How do I fix this?
Running man clang in the Terminal and skimming through, I found this:
The default C++ language standard is gnu++14.
UPDATE: I ran clang++ main.cpp in the compiler and it returned that semicolon error. This isn't a problem with VSCode, so I'll remove that tag.
Here's the error:
main.cpp:3:10: error: expected ';' at end of declaration
int x { 5 };
^
;
1 error generated.

What is the Visual Studio warning equivalent of GCC's -Wreturn-type?

Does Visual Studio have a warning (or warnings) that is the equivalent of GCC's -Wreturn-type?
More specifically, I am looking for a Visual Studio warning (or warnings) that will warn for instances in functions whose return types are not void where
There is a return statement with no return value; or
It is possible function execution could "fall off" the end of the function body without returning a value
I am not concerned with the other part of -Wreturn-type that warns whenever a function is defined with a return type that defaults to int.
For reference, the GCC warning options can be found here.
As pointed out in the comments, this can be done with C4033, C4716, C4715.
User n. 1.8e9-where's-my-share m. also makes a very good point about how to find MSVC warnings in general:
If you want to find out whether a warning that you want exists, just enable all [using /Wall] and test against a small piece of code. If there is a warning, congrats, you found it. If not, tough luck, there isn't any.
I test both with .c and .cpp file extensions, just in case the compiler behaved differently based on the language it is compiling (and sure enough, the behaviour was different for test 2).
None of my tests ever complain about main(), because main() is special, as it is the only function in C and C++ that defaults to returning 0 if no explicit return is provided.
All of the tests below were done using Visual Studio 2015's compiler (i.e., C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\cl.exe), and the commands were issued from the VS2015 x86 Native Tools Command Prompt.
If I am missing any test cases, please leave a comment to let me know.
Tests
C tests
Test 1 - Empty function with int return type
test_warnings.c:
int main() {}
int foo() {}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.c
test_warnings.c
c:\users\administrator\src\test-code\test_warnings.c(3) : error C4716: 'foo': must return a value
Test 2 - Function with int return type with a return without a value
test_warnings.c:
int main() {}
int foo() {
return;
}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.c
test_warnings.c
C:\Users\Administrator\src\test-code\test_warnings.c(4): error C4033: 'foo' must return a value
Test 3 - Function with int return type where execution could "fall off" the end of the function
This test demonstrates that these warnings are not enough, as there is no warning or error emitted for this code.
test_warnings.c:
#include <stdlib.h>
#include <time.h>
int main() {}
int foo() {
int rand_num;
srand(time(0));
rand_num = rand();
if (rand_num > 1) {
return 0;
}
}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.c
test_warnings.c
c:\users\administrator\src\test-code\test_warnings.c(14) : error C4715: 'foo': not all control paths return a value
C++ tests
Test 1 - Empty function with int return type
test_warnings.cpp:
int main() {}
int foo() {}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.cpp
test_warnings.cpp
c:\users\administrator\src\test-code\test_warnings.cpp(3) : error C4716: 'foo': must return a value
Test 2 - Function with int return type with a return without a value
test_warnings.cpp:
int main() {}
int foo() {
return;
}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.cpp
test_warnings.cpp
C:\Users\Administrator\src\test-code\test_warnings.cpp(4): error C2561: 'foo': function must return a value
C:\Users\Administrator\src\test-code\test_warnings.cpp(3): note: see declaration of 'foo'
Test 3 - Function with int return type where execution could "fall off" the end of the function
test_warnings.cpp:
#include <stdlib.h>
#include <time.h>
int main() {}
int foo() {
int rand_num;
srand(time(0));
rand_num = rand();
if (rand_num > 1) {
return 0;
}
}
Compile results:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.cpp
test_warnings.cpp
c:\users\administrator\src\test-code\test_warnings.cpp(14) : error C4715: 'foo': not all control paths return a value
Can you get this with just C4715?
I reran my tests above to see if you can get the same behaviour with just C4715, and here are my results. The command I used for testing this was
cl /nologo /W0 /we4715 <path to file>
Test
C
C++
Test 1
No warning or error
Triggers C4716 as an error, even though this is not turned on (which makes sense, as the docs for this warning say it is automatically promoted to error unless #pragma warning is used to prevent this)
Test 2
No warning or error
Triggers C2561 (a compiler error)
Test 3
Triggers C4715
Triggers C4715
This means C4715 is sufficient for C++, but not sufficient for C.
Notes
C4715 may warn if you call a function that never returns. For example, if you call a function that ends with while (true) {} or throw "error message";. To avoid this, declare the function that never returns with __declspec(noreturn), or if you are using C++11 or newer, you can use the more portable [[noreturn]] in the function declaration. (If you are calling a standard library function like exit(), the compiler will not issue a warning because it will know that function never returns.)
For some interesting related discussion, see Why does flowing off the end of a non-void function without returning a value not produce a compiler error?.

Trivial Eigen3 Tensor program does not build without -On

I'm trying to build a write of software with the Tensor module provided as unsupported from eigen3. I've written a simple piece of code that will build with a simple application of VectorXd (just printing it to stdout), and will also build with an analogous application of Tensor in place of the VectorXd, but WILL NOT build when I do not throw an optimization flag (-On). Note that my build is from within a conda enviromnent that is using conda-forge compilers, so the g++ in what follows is the g++ obtained from conda forge for ubuntu. It says its name in the error messages following, if that is perceived to be the issue.
I have a feeling this is not about the program I'm trying to write, but just in case I've included an mwe.cpp that seems to produce the error. The code follows:
#include <eigen3/Eigen/Dense>
#include <eigen3/unsupported/Eigen/CXX11/Tensor>
#include <iostream>
using namespace Eigen;
using namespace std;
int main(int argc, char const *argv[])
{
VectorXd v(6);
v << 1, 2, 3, 4, 5, 6;
cout << v.cwiseSqrt() << "\n";
Tensor<double, 1> t(6);
for (auto i=0; i<v.size(); i++){
t(i) = v(i);
}
cout << "\n";
for (auto i=0; i<t.size(); i++){
cout << t(i) << " ";
}
cout << "\n";
return 0;
}
If the above code is compiled without any optimizations, like:
g++ -I ~/miniconda3/envs/myenv/include/ mwe.cpp -o mwe
I get the following compiler error:
/home/myname/miniconda3/envs/myenv/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: /tmp/cc2q8gj4.o: in function `Eigen::internal::(anonymous namespace)::get_random_seed()':
mwe.cpp:(.text+0x15): undefined reference to `clock_gettime'
collect2: error: ld returned 1 exit status
If instead I ask for 'n' optimization level, like the following:
g++ -I ~/miniconda3/envs/loos/include/ -On mwe.cpp -o mwe
The program builds without complaint and I get expected output:
$ ./mwe
1
1.41421
1.73205
2
2.23607
2.44949
1 2 3 4 5 6
I have no clue why this little program, or the real program I'm trying to write, would be trying to get a random seed for anything. Any advice would be appreciated. The reason why I would like to build without optimization is so that debugging is easier. I actually thought all this was being caused by debug flags, but I realized that my build tool's debug setting didn't ask for optimization and narrowed that down to the apparent cause. If I throw -g -O1 I do not see the error.
Obviously, if one were to comment out all the code that has to do with the Tensor module, that is everthing in main above 'return' and below the cwiseSqrt() line, and also the include statement, the code builds and produces expected output.
Technically, this is a linker error (g++ calls the compiler as well as the linker, depending on the command line arguments). And you get linker-errors if an externally defined function is called from somewhere, even if the code is never reached.
When compiling with optimizations enabled, g++ will optimize away uncalled functions (outside the global namespace), thus you get no linker errors. You may want to try -Og instead of -O1 for better debugging experience.
The following code should produce similar behavior:
int foo(); // externally defined
namespace { // anonymous namespace
// defined inside this module, but never called
int bar() {
return foo();
}
}
int main() {
// if you un-comment this line, the
// optimized version will fail as well:
// ::bar();
}
According to man clock_gettime you need to link with -lrt if your glibc version is older than 2.17 -- maybe that is the case for your setup:
g++ -I ~/miniconda3/envs/myenv/include/ mwe.cpp -o mwe -lrt

Is this (crash) a bug in VS2012 c++ compiler

I was compiling the following code in c++, Visual Studio 2012 (Professional, Update 4)
class dum {
stringstream *ss;
~dum() {
delete ss;
}
public:
dum() : ss(NULL) {}
};
int main()
{
dum a;
return 0;
}
Now I know that the private destructor would force heap allocated objects only, but I would expect a compile error for that. Instead I get a window titled "Microsoft (R) C/C++ Optimizing compiler" saying
Microsoft (R) C/C++ Optimizing compiler has stopped working. Windows can check online for a solution to the problem
and then the usual prompts to go online where nothing happens (or gets resolved). Am I doing something wrong or have I stumbled upon a bug in the compiler?
EDIT
The code I'm posting is all that's present in a win32 console program (even the main() has this no arguments form) and the only header included is sstream.
If you move the destructor to the public section of the class we no longer have a crash, but as I mentioned above this should be a cause for compilation error (namelly cannot access private member declared in dum) and not for this pop-up. The question's targeted to people that can provide an intrinsic or two about what's the problem with the compiler here, I've seen similar problems before, but that's the smallest code segment that caused such a thing.
Trying to compile the fixed version:
#include <sstream>
using namespace std;
class dum {
stringstream *ss;
~dum() {
delete ss;
}
public:
dum() : ss(NULL) {}
};
int main()
{
dum a;
return 0;
}
gives following compile error for me.
Tried this with VS2012 Ultimate Version 11.061030.00 Update4.
1>------ Build started: Project: dum, Configuration: Debug Win32 ------
1> dum.cpp
1>c:\users\randmaniac\documents\visual studio 2012\projects\dum\dum\dum.cpp(19): error C2248: 'dum::~dum' : cannot access private member declared in class 'dum'
1> c:\users\randmaniac\documents\visual studio 2012\projects\dum\dum\dum.cpp(8) : see declaration of 'dum::~dum'
1> c:\users\randmaniac\documents\visual studio 2012\projects\dum\dum\dum.cpp(6) : see declaration of 'dum'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
No crash for me on a fairly recent installation of VS2012.

running shellcode + vs2010

I just tried the following code snippet for shellcode testing purposes:-
#include<iostream>
using namespace std;
char sc[] = ""; #i've removed the shellcode
int main() {
int (*func)();
func = (int(*)())sc;
(int)(*func)();
}
I get a build error on compilation :-
------ Build started: Project: shellcoderunner, Configuration: Debug Win32 ------
Build started 10/15/2011 12:51:16 PM.
InitializeBuildStatus:
Touching "Debug\shellcoderunner.unsuccessfulbuild".
ClCompile:
blah.cpp
c:\users\reverser\documents\visual studio 2010\projects\shellcoderunner\shellcoderunner\blah.cpp(7): error C2440: 'type cast' : cannot convert from 'char [149]' to 'int (__cdecl *)(void)'
There is no context in which this conversion is possible
Build FAILED.
Time Elapsed 00:00:01.99
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Something obvious that I'm doing wrong?
To execute a shellcode in your C/C++ program with VS, the simplest way is embedding an Assembly code like this example below:
char* buffer="blah blah blah";
int main() {
__asm{
lea eax, buffer
call eax
}
}
Hope this help!
[
At the time I am answering the question is about why compilation fails for …
#include<iostream>
using namespace std;
char sc[] = ""; #i've removed the shellcode
int main() {
int (*func)();
func = (int(*)())sc;
(int)(*func)();
}
This code is an attempt to execute data bytes as machine code. However, the OP calls this a “code snippet for shellcode testing purposes”, which is unrelated. And so I am including this original context.
]
You may have success using a void* as intermediary.
In the formal even that should not compile, because in the formal a data pointer cannot be converted to a function pointer or vice versa.
However, reportedly Posix requires the ability to do that conversion, and it's old existing practice, so I believe most if not all compilers support it.
Note that you are in UB-land as regarding effects.
Also, note that anti-virus software and page level execute permission checking may disagree a bit with trying to execute the bytes in a string as machine code, so at that higher level yes you're doing something obviously wrong. ;-)
By the way, if what you are trying to achieve is to execute a shell script, then look into the system function.
What command to pass in the system call would depend on your system, so if you change your question be sure to include information about that.
Cheers & hth.,
I think the following should work:
char sc[] = ""; // i've removed the shellcode
int main()
{
int (*func)() = (int(*)())sc; // C++
int (*func)() = sc; /* C */
func();
}
It's technically undefined behaviour, but then again that's the whole point of shellcode.
You cannot cast an array to a function pointer. You have to first acquire a pointer to the array, which then can be cast:
func = (int(*)())&sc;