Q about "optimizing away" "non-used" code

J

J. Campbell

From reading this forum, it is my understanding that C++ doesn't
require the compiler to keep code that does not manifest itself in any
way to the user. For example, in the following:
{
for(int i = 0; i < 10; ++i){
std::cout << i << std::endl;
for(int j = 0; j < 0x7fffffff; ++j){}
}
}

since j is not "used" the compiler can simply get rid of the j-loop.
The question is this: Can an optimizing compiler ignore a memset()
command if the memory pointed to is never again accessed after the
memset() command?

For example, in the following code:
int main(){
int* a = new int[100];

// some code that uses a

memset(a, 0, 100 * sizeof(*a));
delete [] a;
return 0;
}

is the compiler *obligated* to overwrite the memory used by a before
the program returns, or can the memset line be "optimized away" since
that memory isn't used to produce output later in the program?

The real question is can memset be used to assure that a program's
data is purged from memory before exiting?
 
C

Chris Theis

J. Campbell said:
From reading this forum, it is my understanding that C++ doesn't
require the compiler to keep code that does not manifest itself in any
way to the user. For example, in the following:
{
for(int i = 0; i < 10; ++i){
std::cout << i << std::endl;
for(int j = 0; j < 0x7fffffff; ++j){}
}
}

since j is not "used" the compiler can simply get rid of the j-loop.
The question is this: Can an optimizing compiler ignore a memset()
command if the memory pointed to is never again accessed after the
memset() command?

Getting rid of an empty loop is a trivial optimization but optimizing away
whole function calls is a different issue.
For example, in the following code:
int main(){
int* a = new int[100];

// some code that uses a

memset(a, 0, 100 * sizeof(*a));
delete [] a;
return 0;
}

is the compiler *obligated* to overwrite the memory used by a before
the program returns, or can the memset line be "optimized away" since
that memory isn't used to produce output later in the program?

IMHO theoretically the compiler might be allowed to optimize away this
function call, though I doubt that it will do it as the analysis for this is
more complicated than finding an empty loop. However, if you want to be sure
you should take a look at the machine code that your specific compiler
produces. In case you still find such unwanted optimization you can still
turn it off anyway.
The real question is can memset be used to assure that a program's
data is purged from memory before exiting?

Why is that so important for you?

HTH
Chris
 
K

Karl Heinz Buchegger

J. Campbell said:
since j is not "used" the compiler can simply get rid of the j-loop.
The question is this: Can an optimizing compiler ignore a memset()
command if the memory pointed to is never again accessed after the
memset() command?

memset is not a command (in general there are no commands in C++)
memset is a function.
For example, in the following code:
int main(){
int* a = new int[100];

// some code that uses a

memset(a, 0, 100 * sizeof(*a));
delete [] a;
return 0;
}

is the compiler *obligated* to overwrite the memory used by a before
the program returns, or can the memset line be "optimized away" since
that memory isn't used to produce output later in the program?

Hmm. Optimization in C++ is under the influence of one rule:
as - if.

That means that the compiler is allowed to rearange everything, as long
as the observable behaviour is as-if the rearrangment hasn't taken
place (with one exception, but this is unimportant right now). So
in principle, if it is a very smart compiler, it could do the
above optimization, if the compiler takes the behaviour of
memset into account. As far as the compiler is concerned,
memset is just a call to a function. On the other hand it is a
standard function, and of course the compiler could inline it
thus eliminating the function call at all which leaves us with
a sort of 'assignment to memory'.
A smart compiler doing data flow anaylsis could also figure
out the point of memory destruction and working backwards from
that point it could throw away all assignments to that memory
until it hits the last read from that memory.

So in principle it is possible. If any compiler does this:
I don't know. Test your compiler.
 
T

Thomas Matthews

J. Campbell said:
From reading this forum, it is my understanding that C++ doesn't
require the compiler to keep code that does not manifest itself in any
way to the user.


There are two cases about unused code: code not used within a function
and entire functions that are not used. As far as the first case goes,
it is up to the compiler and how it feels about optimizing. The latter
case is up to the linking portion. Some lazy linkers link in everything
{including libraries) to speed up the process. More optimal linkers
will omit functions that are not executed.

For example, in the following:
{
for(int i = 0; i < 10; ++i){
std::cout << i << std::endl;
for(int j = 0; j < 0x7fffffff; ++j){}
}
}

since j is not "used" the compiler can simply get rid of the j-loop.
The question is this: Can an optimizing compiler ignore a memset()
command if the memory pointed to is never again accessed after the
memset() command?

No. There are instances where the area of memory needs to be cleared,
or erased before the function is exited. One scenario is cryptography,
where secret keys must be erased before the function is terminated.
For example, in the following code:
int main(){
int* a = new int[100];

// some code that uses a

memset(a, 0, 100 * sizeof(*a));
delete [] a;
return 0;
}

is the compiler *obligated* to overwrite the memory used by a before
the program returns, or can the memset line be "optimized away" since
that memory isn't used to produce output later in the program?

Yes, because in the above scenario, the allocated data is erased to
"leave no trace".
The real question is can memset be used to assure that a program's
data is purged from memory before exiting?

The memset function has no relation to the allocation or deallocation
of memory (purging). The function's only responsibility is to set
an area of memory to a given value. The memset function can be
applied to fixed (static) areas also.

The C++ language does not require an implementation to purge or
erase any memory regions. This _could_ be an operating system
issue; after all, the operating system is in charge of loading
a program into memory and executing it, then recovering the
memory.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
S

Stewart Gordon

While it was 21/1/04 3:21 pm throughout the UK, Thomas Matthews
sprinkled little black dots on a white screen, and they fell thus:
There are two cases about unused code: code not used within a function
and entire functions that are not used.

That's not what the OP is talking about. In the given example, the code
_is_ used, the only variable declared within it _is_ used, it merely has
no overall effect.

Surely almost any compiler is going to optimise away unreachable code,
such as that immediately following a break or return in its block with
no label leading to it.

A half-decent compiler would probably do the same with conditions that
are obviously either always true or always false.

A null-effect loop like the OP's example just might be cut out.
However, it cannot know for sure that the programmer wasn't intending to
count up to 0x7fffffff as a processor speed benchmark, or to make a game
run at the right speed on an 8MHz 8086 while having it unplayable on
anything made in the last 15 years.

No. There are instances where the area of memory needs to be cleared,
or erased before the function is exited. One scenario is cryptography,
where secret keys must be erased before the function is terminated.

Obviously the decrypted data (or data not yet encrypted) would need to
be erased just as well.

The memset function has no relation to the allocation or deallocation
of memory (purging).
<snip>

Exactly. But it's purging of data that's the question here.

Stewart.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top