473,387 Members | 1,798 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Questions about compilers const optimizations

The following code compiled with gcc version 3.3.4 20040623 (Gentoo
Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6) produce a segmentation fault
and has a size
of 9095 byte on my machine:

#include <iostream>

using namespace std;

const bool v = true;

void modifyConst() {

const bool tmp = v;

const_cast<bool&>(v) = !tmp;

return;
}

int main() {

do {
if (v) {

cout << "FOREVER HERE?!?!" << endl;

modifyConst();
}

else {
cout << "THIS CODE WILL NOT BE GENERATED?!" << endl;
}
}

while(v);
}

The same code with "bool v = true;" instead of "const bool v = true;"
has a size of 9184 byte and runs with no error.

Had the compiler removed the 'else branch' and the 'while cmp
instruction' only looking at the const declaration? If so, why it
can't handle the assignment (with cast) in the modifyConst? It should
be able to understand that what was previously considered a 'safe
const' (regarding to optimizations and expressions reduction) now is
no more a 'safe' one.

Thanks,

Gianguglielmo
Jul 22 '05 #1
9 1504
Gianguz wrote:
[..] why it
can't handle the assignment (with cast) in the modifyConst? It should
be able to understand that what was previously considered a 'safe
const' (regarding to optimizations and expressions reduction) now is
no more a 'safe' one.


I think you need to ask in gnu.g++.help or gnu.g++.bugs (if you consider
it a bug), but from the C++ point of view whatever you did (assignment to
a const object by casting away constness) has _undefined_behaviour_ and no
specific requirement is imposed.

V
Jul 22 '05 #2
gi*****************@noze.it (Gianguz) wrote in
news:af**************************@posting.google.c om:
The following code compiled with gcc version 3.3.4 20040623 (Gentoo
Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6) produce a segmentation fault
and has a size
of 9095 byte on my machine:

#include <iostream>

using namespace std;

const bool v = true;

void modifyConst() {

const bool tmp = v;

const_cast<bool&>(v) = !tmp;
Program may do anything it wants to at this point. You are modifying a
const object, and thus Undefined Behaviour is invoked.
return;
}

int main() {

do {
if (v) {

cout << "FOREVER HERE?!?!" << endl;

modifyConst();
}

else {
cout << "THIS CODE WILL NOT BE GENERATED?!" << endl;
}
}

while(v);
}

The same code with "bool v = true;" instead of "const bool v = true;"
has a size of 9184 byte and runs with no error.

Had the compiler removed the 'else branch' and the 'while cmp
instruction' only looking at the const declaration? If so, why it
It might. Depends on the compiler. Wouldn't surprise me though. Since
v is always true (it's const, remember?), why bother to generate the else
clause, it will never be executed.
can't handle the assignment (with cast) in the modifyConst? It should
be able to understand that what was previously considered a 'safe
const' (regarding to optimizations and expressions reduction) now is
no more a 'safe' one.


Huh? Why should it even attempt to "handle the assignment". You casted
away the constness of an object, and then attempted to modify it. The
compiler has absolutely no obligation to do _anything_ sane with that
code construct.
Jul 22 '05 #3
"Gianguz" <gi*****************@noze.it> wrote in message
news:af**************************@posting.google.c om...
The following code compiled with gcc version 3.3.4 20040623 (Gentoo
Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6) produce a segmentation fault
and has a size
of 9095 byte on my machine:

#include <iostream>

using namespace std;

const bool v = true;

void modifyConst() {

const bool tmp = v;

const_cast<bool&>(v) = !tmp;

return;
}

int main() {

do {
if (v) {

cout << "FOREVER HERE?!?!" << endl;

modifyConst();
}

else {
cout << "THIS CODE WILL NOT BE GENERATED?!" << endl;
}
}

while(v);
}

The same code with "bool v = true;" instead of "const bool v = true;"
has a size of 9184 byte and runs with no error.

Had the compiler removed the 'else branch' and the 'while cmp
instruction' only looking at the const declaration? If so, why it
can't handle the assignment (with cast) in the modifyConst? It should
be able to understand that what was previously considered a 'safe
const' (regarding to optimizations and expressions reduction) now is
no more a 'safe' one.

Thanks,

Gianguglielmo


It could be that gcc has allocated space for "v" in read-only memory, seeing
that you declared it const. The segmentation fault would then be the
consequence of trying to change it. This is perfectly legal behavior since
the effect of trying to change a "const" item as you are doing is undefined.

David

Jul 22 '05 #4
Modifying an object that is defined as const gives undefined behavior.
The compiler doesn't have to detect it, doesn't have to diagnose it,
and has no obligation to handle it in any particular fashion.

Bottom line: you've lied to the compiler, and when you do that, it WILL
get its revenge.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 22 '05 #5
The point is that the compiler is able to put into read-only memory
only const built-in types
initialized to value known at compile time. Any other const allocation
belongs to the same mechanism of non-const ones. So, even if not so
'legal', it is really safe the following:

class Const {
public:
const bool _const;
Const() : _const(false) { }
};

const Const v;

int main() {
bool value = true;
do {
value = !value;
const_cast<bool&>(const_cast<Const&>(v)._const) = value;
}
while(1);
}
Cheers,

Gianguglielmo

Jul 22 '05 #6
gi*****************@noze.it wrote:
The point is that the compiler is able to put into read-only memory
only const built-in types
initialized to value known at compile time. Any other const allocation
belongs to the same mechanism of non-const ones. So, even if not so
'legal', it is really safe the following:

class Const {
public:
const bool _const;
Const() : _const(false) { }
};

const Const v;

int main() {
bool value = true;
do {
value = !value;
const_cast<bool&>(const_cast<Const&>(v)._const) = value;
}
while(1);
}


Hold on a minute... Are you saying that '::v' in your code is initialised
with something other than a constant value? While it has a "non-trivial"
constructor, what is there to prevent the compiler from figuring out the
intialisation of '::v' at the compile-time? I can't find anything in the
Standard saying that the compiler shall not create such object in
read-only storage if it can. So, pardon me, until proven otherwise, I
will not consider "not legal" "safe".

V
Jul 22 '05 #7
I think you should have to check the following code and the Stroustrup
3d edition at section 5.4 "Constants".
Anyway you are not compelled to trust me or to consider that "legal"
code "safe"! ;)

const bool f(const int x) {

for(int i=0; i<x; i++)

if (x - i > i + i)

return true;

else

return false;

return false;
}

const bool const0 = f(0);

const bool const1 = (const0 && f(const0));

const bool const2 = (false && f(const0));

class Const {

public:

const bool const3;

Const() : const3(true) { }

~Const() { }
};

const Const v;

int main() {

bool value = true;

do {

value = !value;

//1) this is safe
const_cast<bool&>(const0) = value;

//2) this is safe because even if const0=f(0)=false and
f(const0)=f(0)=false compilers doesn't understand that
const_cast<bool&>(const1) = value;

//3) this make the program crash because compilers knows that
const2 = false so it doesn't reserve memory for it that can be later
referred...try to comment it! ;)
const_cast<bool&>(const2) = value;

//4) also this is safe
const_cast<bool&>(const_cast<Const&>(v).const3) = value;
}

while(1);
}

Jul 22 '05 #8
gianguz wrote:
I think you should have to check the following code and the
Stroustrup 3d edition at section 5.4 "Constants".
Anyway you are not compelled to trust me or to consider that
"legal" code "safe"! ;)


I don't know about "safe". I'd say "won't cause a segmentation fault
under gcc's current methods of handling const". gcc only puts a const
in readonly memory if its value can be determined at compile time.
That's a fine thing to understand if you're curious, but it is a fact
about specific implementations of gcc, not about C++.

const_cast is mainly useful for interfacing to old APIs that are not
const correct. For example, strcmp is defined like this,

int strcmp(const char *s1, const char *s2);

But imagine an application has its own case-insensitive strcmp, but
that it is not const correct,

// Case-insensitive strcmp!
// Documentation says it does not modify its arguments.
int str_i_cmp(char *s1, char *s2);

Since it does not modify its arguments, the they should have been
declared const char * but they were not. This is a hassle if you have
to call it with const char * arguments, but since you know the function
does not modify the arguments, you can cast the const away to make the
call.

I can't think of anything else const_cast is good for.
--
Dave O'Hearn

Jul 22 '05 #9
Dave O'Hearn wrote:

const_cast is mainly useful for interfacing to old APIs that are not
const correct. For example, strcmp is defined like this,

int strcmp(const char *s1, const char *s2);

I partially agree
But imagine an application has its own case-insensitive strcmp, but
that it is not const correct,

// Case-insensitive strcmp!
// Documentation says it does not modify its arguments.
int str_i_cmp(char *s1, char *s2);

Since it does not modify its arguments, the they should have been
declared const char * but they were not. This is a hassle if you have
to call it with const char * arguments, but since you know thedeclare function does not modify the arguments, you can cast the const away to make the call.

I can't think of anything else const_cast is good for.
For example you can have a class method const bool foo(const X* ptr)
that does not modify X pointed by ptr. In foo's body you refers to N
const method of the pointed instance but you need only 1 (for instance)
temporary access to a non-const data member of that object instance.
Your function is stricter then the general case needed and safest.

The problem is that i don't think const allocation in read-only depends
on the compiler. Do you know about compilers able to do the following:

const bool f(const int x) {

for(int i=0; i<x; i++)

if (x - i > i + i)

return true;

else
return false;

return false;
}

int main() {

const bool value = f(0);
//at this point a compiler should be able to allocate a compile
//time known const into read-only memory in a dynamical way...mmmm...
const bool tmp = *(new const bool(true));

while(1) {

const_cast<bool&>(value) = !tmp;

const_cast<bool&>(tmp) = value;
}
}

I think that read-only memory can only be allocated during
the program startup, but i need confirmations of that. --
Dave O'Hearn


Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

83
by: user | last post by:
Hello, Here is the program #include stdio int main(void) { const int num = 100; int *ip;
50
by: Joseph Casey | last post by:
Greetings. I have read that the mistake of calling free(some_ptr) twice on malloc(some_data) can cause program malfunction. Why is this? With thanks. Joseph Casey.
20
by: Snis Pilbor | last post by:
Whats the point of making functions which take arguments of a form like "const char *x"? It appears that this has no effect on the function actually working and doing its job, ie, if the function...
66
by: KimmoA | last post by:
Hey! Some questions about C that have been bugging me for a while... 1) Is inline a valid C keyword or not? I was kind of surprised of not finding it in C, to be honest. My "The C Programming...
3
by: llothar | last post by:
I'm using SmallEiffel - which is more or less a huge preprocessor - for C. It has the option to compile the whole Eiffel program into one huge C file but doesn't add a static declaration to the...
20
by: liujiaping | last post by:
I'm confused about the program below: int main(int argc, char* argv) { char str1 = "abc"; char str2 = "abc"; const char str3 = "abc"; const char str4 = "abc"; const char* str5 = "abc";
23
by: Kira Yamato | last post by:
It is erroneous to think that const objects will have constant behaviors too. Consider the following snip of code: class Person { public: Person(); string get_name() const
11
by: Alexander Adam | last post by:
Hi there! I've got a few (more generic) questions for those C++ experts out there. 1. I am trying to store any kind of data (custom PODs, numbers, strings etc.) within some kind of stream...
13
by: Adem | last post by:
HOWTO: const and pointer variants in C and C++ : void test() { int n = 1; // n is non-const data of type int ++n; // ok const int c = 2; //...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.