top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

constant behaviour in C

–1 vote
244 views

Please look at this simple code..

#include <iostream>
using namespace std;

void fun(const int *p) {
    int *q = (int *)p;
    int tmp = 6;
    memcpy(q, &tmp, 4);
}

int main() {
    int foo = 5;
    const int *p = &foo;
    cout << foo << endl;
    fun(p);
    cout << foo << endl;
    return 0;
}

result: 5 6

I don't think foo should not changeable.

posted Mar 12, 2013 by Salil Agrawal

Share this question
Facebook Share Button Twitter Share Button LinkedIn Share Button

2 Answers

+1 vote
 
Best answer

Well since you told the compiler to ignore the const, you're getting
undefined behaviour.

Turn the warnings up on your compiler and you'll see it complain:

[pherring@thinkpad-pjh tmp]$ cat const.cpp
#include <iostream>
#include <cstring>

using namespace std;

void fun(const int *p) {
        int *q = (int *)p;
        int tmp = 6;
        memcpy(q, &tmp, 4);
}

int main() {
        int foo = 5;
        const int *p = &foo;
        cout << foo << endl;
        fun(p);
        cout << foo << endl;
        return 0;
}
[pherring@thinkpad-pjh tmp]$ g++ const.cpp -o const -g -O -Wall -Weffc++
-pedantic  -pedantic-errors -Wextra  -Wall -Waggregate-return -Wcast-align
-Wcast-qual  -Wchar-subscripts  -Wcomment -Wconversion
-Wdisabled-optimization -Werror -Wfloat-equal  -Wformat  -Wformat=2
-Wformat-nonliteral -Wformat-security  -Wformat-y2k -Wimplicit  -Wimport
-Winit-self  -Winline -Winvalid-pch   -Wunsafe-loop-optimizations
-Wlong-long -Wmissing-braces -Wmissing-field-initializers
-Wmissing-format-attribute   -Wmissing-include-dirs -Wmissing-noreturn
-Wpacked  -Wpadded -Wparentheses  -Wpointer-arith -Wredundant-decls
-Wreturn-type -Wsequence-point  -Wshadow -Wsign-compare  -Wstack-protector
-Wstrict-aliasing -Wstrict-aliasing=2 -Wswitch  -Wswitch-default
-Wswitch-enum -Wtrigraphs  -Wuninitialized -Wunknown-pragmas
-Wunreachable-code -Wunused -Wunused-function  -Wunused-label
-Wunused-parameter -Wunused-value  -Wunused-variable  -Wvariadic-macros
-Wvolatile-register-var  -Wwrite-strings
cc1plus: warnings being treated as errors
const.cpp: In function ‘void fun(const int*)’:
const.cpp:7:18: error: cast from type ‘const int*’ to type ‘int*’ casts
away qualifiers
[pherring@thinkpad-pjh tmp]$
answer Mar 12, 2013 by anonymous
0 votes

Declaring *const int ** is equals to *int const ** i.e pointer to constant integer. Attribute of constant integer is one can not change its content and will give you compilation error if you do so.

But we can change the content of constant integer using pointer to integer. By looking at the below code, p is not pointing to constant integer, will not give you compile time error and hence will allow to change the content of foo.

Hope this helps.

answer Mar 14, 2013 by anonymous
Similar Questions
+1 vote

I wanted to ask what is the GCC C++ equivalent implementation of Windows _ MyFirst and _MyLast vector pointers?

These give direct access to the vectors first and last element, but they are not present in the GCC implementation of the vector class.

+1 vote

I have an oversight in my code where I'm declaring & defining a function
with C-linkage, though it's not possible.

Example snippet:

#ifdef __cplusplus
extern "C"
{
#endif

// ... some functions which are compatible with C linkage

// Intended to be a helper function not exposed from library
std::string GetEngineVersion()
{
 // ...
}

#ifdef __cplusplus
}
#endif

Obviously the GetEngineVersion function cannot have C linkage because it returns a C++ class.

My question is: does GCC have a warning for this scenario? Specifically, can it warn when something is declared extern "C" that's incompatible with C linkage?

I compile with the following warning flags and I didn't get a warning:

-Wall -Wunused-parameter -Wextra -Weffc++ -Wctor-dtor-privacy
-Wnon-virtual-dtor -Wreorder -Wold-style-cast -Woverloaded-virtual
-Werror

Incidentally, when I compile the same code in VS2013 I get this warning:

warning C4190: 'GetEngineVersion' has C-linkage specified, but returns UDT 'std::basic_string' which is incompatible with C
0 votes

how can I configure GCC to emit the calls to __cxa_thread_atexit() for destructor registration? On a Linux PowerPC target I see the registration of destructors, but not on the powerpc-rtems target. I guess I missed a configuration option or define. Has someone a hint for me?

0 votes

I've noticed the difference in gcc and llvm behaviour with the following code:

$ cat test.c

int main()
{
 for(int i = 0;; ({break;}))
 printf("Hello, worldn");
}

$ clang test.c -pedantic &; ({break;}))
1 warning generated.
Hello, world

$ gcc test.c -std=gnu11 -pedantic &; ({break;}))
test.c:5:21: warning: ISO C forbids braced-groups within expressions [-Wpedantic]
 for(int i = 0;; ({break;}))

So, llvm thinks that this is GNU extension (seems like it really is), but compiles it, and gcc does not, even if the standard is specified as gnu11. Is it a bug?

0 votes

I recently encountered a problem with a function was marked as a constructor. The source file was compiled with -O0, but it appears the function was optimized to the point it skipped some of the startup
code and jumped into the failure state (which called exit). I was able to restore desired behavior with '#pragma GCC optimize("O0")' around the function (even volatile tricks did not help).

The startup code had to do with an integrity check. The expected fingerprint was back-patched after compiling, and then recalculated at runtime. Then, a memcmp was made. It appears the compiler deduced that the allocation was a string of 0's and could never be equal to the runtime fingerprint, so its just omitted the code.

Is this expected behavior for functions marked as constructors (compiled with -O0)?

...