By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,603 Members | 1,461 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,603 IT Pros & Developers. It's quick & easy.

Optimizing Away

P: n/a
Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined):

static int G_num_loops = 0;

void main (void)
{
/* set up interrupts */
/* ... */
for ( ; ; )
{
G_num_loops++;
}
}

Further suppose that I have the (non-standard) means to "read" the value
of G_num_loops via a link map and other techniques :)

Is there anything in the C standard that allows the compiler to
optimize away and NOT allocate storage for G_num_loops and thus prevent me
from "viewing" its value? If so, does defining G_num_loops as volatile
prevent this? (or put in a more standard kind of way, does the C standard
require the statement:

G_num_loops++;

to be executed.

My compiler seems to be optimizing that statement away when defined as
static and not volatile. So instead, I change the definition to have
external linkage:

int G_num_loops = 0;

and it works for my purpose.

The only *potential* problem is that if I define variables with the
same name (mostly arrays) with external linkage in another translation
unit (more likely the name would be G_debug_buf), then the linker issues
an error about multiply defined symbols.

I can deal with that--I've learned to "work" with the compiler and
linker and just name such variables with prefixes that are specific to the
module, e.g., G_fir_debug_buf or G_serial_debug_buf. Maybe I'm just facing
the reality of embedded debugging, but I'd like to hear the opinions of
others who have similar experience in this area.

BTW, the compiler I'm working with does not conform to the C standard in
that it does not initialize the following file scope definition to 0:

static int G_num_loops;

I have to explicitly initialize it to 0:

static int G_num_loops = 0;

Thanks
--
jay

Nov 15 '06 #1
Share this Question
Share on Google+
26 Replies


P: n/a
jaysome <ja*****@spamcop.netwrote:
Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined):

static int G_num_loops = 0;

void main (void)
{
/* set up interrupts */
/* ... */
for ( ; ; )
{
G_num_loops++;
}
}

Further suppose that I have the (non-standard) means to "read" the value
of G_num_loops via a link map and other techniques :)

Is there anything in the C standard that allows the compiler to
optimize away and NOT allocate storage for G_num_loops and thus prevent me
from "viewing" its value?
Yes.
If so, does defining G_num_loops as volatile prevent this?
Keeping in mind that volatile is intentionally under-specified, yes, it
should.
(or put in a more standard kind of way, does the C standard
require the statement:

G_num_loops++;

to be executed.
No. It requires the program to behave _as if_ it were executed, but if
there's nothing in the program itself which can detect whether it is, or
even detect whether G_num_loops exists at all, it's allowed to leave it
out and only pretend to have increment an int. That you might also be
able to read its value using means outside the program itself is not
within the scope of the S Standard, and an implementation is allowed to
ignore it.

Making G_num_loops volatile should, as you expect, stop this. All
accesses of a volatile object must be performed exactly as the Standard
specifies, with no optimisation performed on it. The catch is that "What
constitutes an access ... is implementation-defined".
An implementation could theoretically define an access as any reading of
a volatile object for the purposes of assigning it to another object, or
writing a value in it from another object. Since G_num_loops++ involves
only its own previous and next value, this would not constitute an
access under such an implementation. That implementation would, however,
be perverse - strictly within the bounds of the Standard, but perverse -
and I wouldn't take it into account in practice.

Richard
Nov 15 '06 #2

P: n/a

jaysome wrote:
Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined):

static int G_num_loops = 0;

void main (void)
{
/* set up interrupts */
/* ... */
for ( ; ; )
{
G_num_loops++;
}
}

Further suppose that I have the (non-standard) means to "read" the value
of G_num_loops via a link map and other techniques :)

Is there anything in the C standard that allows the compiler to
optimize away and NOT allocate storage for G_num_loops and thus prevent me
from "viewing" its value? If so, does defining G_num_loops as volatile
prevent this? (or put in a more standard kind of way, does the C standard
require the statement:

G_num_loops++;

to be executed.

My compiler seems to be optimizing that statement away when defined as
static and not volatile. So instead, I change the definition to have
external linkage:

int G_num_loops = 0;

and it works for my purpose.

The only *potential* problem is that if I define variables with the
same name (mostly arrays) with external linkage in another translation
unit (more likely the name would be G_debug_buf), then the linker issues
an error about multiply defined symbols.

I can deal with that--I've learned to "work" with the compiler and
linker and just name such variables with prefixes that are specific to the
module, e.g., G_fir_debug_buf or G_serial_debug_buf. Maybe I'm just facing
the reality of embedded debugging, but I'd like to hear the opinions of
others who have similar experience in this area.

BTW, the compiler I'm working with does not conform to the C standard in
that it does not initialize the following file scope definition to 0:

static int G_num_loops;

I have to explicitly initialize it to 0:

static int G_num_loops = 0;

Thanks
--
jay
Defining G_num_loops as volatile will prevent it from being optimized
out. In embedded applications, you should use the volatile keyword to
describe any variables that you are mapping to a hardware register.

Nov 15 '06 #3

P: n/a
in********@gmail.com wrote:
Defining G_num_loops as volatile will prevent it from being optimized
out. In embedded applications, you should use the volatile keyword to
describe any variables that you are mapping to a hardware register.
Right. In addition to hardware registers and memory mapped devices,
other situations require the use of volatile:

1) Variables shared between threads.
2) Variables shared between threads and Interrupt Service routines.
3) Local variables in functions were setjmp has been called . This is
an exotic and used in few situations, but worth to mention.

Nov 15 '06 #4

P: n/a
jaysome wrote:
static int G_num_loops = 0;

void main (void)
{
/* set up interrupts */
/* ... */
for ( ; ; )
{
G_num_loops++;
}
}

In case you are accessing G_num_loops from an
interrupt handler, I would use:

volatile static sig_atomic_t G_num_loops;

volatile will stop the compiler from optimizing away your

G_num_loops++;

--
Tor <torust AT online DOT no>

Nov 15 '06 #5

P: n/a
jaysome wrote:
>
Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined):

static int G_num_loops = 0;

void main (void)
Even if it is defined for your peculiar system, why use it? All
you are doing is creating another needless incompatibility.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Nov 16 '06 #6

P: n/a
CBFalconer <cb********@yahoo.comwrites:
jaysome wrote:
>>
Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined):

static int G_num_loops = 0;

void main (void)

Even if it is defined for your peculiar system, why use it? All
you are doing is creating another needless incompatibility.
A freestanding implementation is free to say that "void main(void)"
is legal and "int main(void)" isn't. The requirement
that an implementation must accept "int main(void)" and
"int main(int argc, char *argv[])" applies *only* to hosted
environments.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 16 '06 #7

P: n/a
On Wed, 15 Nov 2006 17:03:39 -0500, CBFalconer <cb********@yahoo.com>
wrote:
>jaysome wrote:
>>
Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined):

static int G_num_loops = 0;

void main (void)

Even if it is defined for your peculiar system, why use it? All
you are doing is creating another needless incompatibility.
Because if I define main() with a return type of int, and I have
something like this:

int main(void)
{

for ( ; ; )
{
/* do something */
}

return 0;
}

then some compilers and PC-lint complain about the "return 0;"
statement being unreachable.

Using void main(void) is appropriate for most embedded applications
that I can think of. Furthermore, most embedded applications are
"incompatible" (which I assume implies "portable") by there very
nature, so "creating another needless incompatibility" is really a non
sequitur.

I prefer to use void main(void) in embedded applications, where it
makes sense, because my main() will never return, and that's how it's
designed to work.

Sometimes it makes sense to shed your pedantic sunglasses when dealing
with the real world.

Best regards
--
jay
Nov 16 '06 #8

P: n/a
On 15 Nov 2006 15:24:57 -0800, "Tor Rustad" <to********@hotmail.com>
wrote:
>jaysome wrote:
>static int G_num_loops = 0;

void main (void)
{
/* set up interrupts */
/* ... */
for ( ; ; )
{
G_num_loops++;
}
}


In case you are accessing G_num_loops from an
interrupt handler, I would use:

volatile static sig_atomic_t G_num_loops;

volatile will stop the compiler from optimizing away your

G_num_loops++;
Tor:

I think you are correct. Until reading your post I'd never heard of
the type sig_atomic_t.

Unfortunately, my compiler does not define the sig_atomic_t type. All
it has is a comment in <stdint.h>:

/* sig_atomic_t not defined */

Thanks
--
jay
Nov 16 '06 #9

P: n/a
jaysome wrote:
>
.... snip ...
>
I think you are correct. Until reading your post I'd never heard
of the type sig_atomic_t.

Unfortunately, my compiler does not define the sig_atomic_t type.
All it has is a comment in <stdint.h>:

/* sig_atomic_t not defined */
It should be defined in <signal.h>

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Nov 16 '06 #10

P: n/a
jaysome wrote:
>
Tor:

I think you are correct. Until reading your post I'd never heard of
the type sig_atomic_t.
OK, sig_atomic_t was defined in C89
Unfortunately, my compiler does not define the sig_atomic_t type. All
it has is a comment in <stdint.h>:

/* sig_atomic_t not defined */
Did you check in <signal.h>?

--
Tor <torust AT online DOT no>

Nov 16 '06 #11

P: n/a
jaysome <ja*****@spamcop.netwrites:
On Wed, 15 Nov 2006 17:03:39 -0500, CBFalconer <cb********@yahoo.com>
wrote:
>>jaysome wrote:
>>>
Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined):

static int G_num_loops = 0;

void main (void)

Even if it is defined for your peculiar system, why use it? All
you are doing is creating another needless incompatibility.

Because if I define main() with a return type of int, and I have
something like this:

int main(void)
{

for ( ; ; )
{
/* do something */
}

return 0;
}

then some compilers and PC-lint complain about the "return 0;"
statement being unreachable.

Using void main(void) is appropriate for most embedded applications
that I can think of. Furthermore, most embedded applications are
"incompatible" (which I assume implies "portable") by there very
nature, so "creating another needless incompatibility" is really a non
sequitur.

I prefer to use void main(void) in embedded applications, where it
makes sense, because my main() will never return, and that's how it's
designed to work.
Sure, that makes sense *if* your implementation documents
"void main(void)" as valid declaration for main.

If it doesn't, you're risking undefined behavior. Personally, I'd
rather put up with a warning message than take that risk. YMMV.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 16 '06 #12

P: n/a
CBFalconer wrote:
jaysome wrote:

Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined):

Even if it is defined for your peculiar system, why use it? All
you are doing is creating another needless incompatibility.
In a freestanding environment, the type (and name!) of
startup function, is implementation-defined.

So what (in)compatibility are you talking about?

--
Tor <torust AT online DOT no>

Nov 16 '06 #13

P: n/a
Keith Thompson wrote:
jaysome <ja*****@spamcop.netwrites:
On Wed, 15 Nov 2006 17:03:39 -0500, CBFalconer <cb********@yahoo.com>
wrote:
>jaysome wrote:

Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined)
[...]
Sure, that makes sense *if* your implementation documents
"void main(void)" as valid declaration for main.

If it doesn't, you're risking undefined behavior. Personally, I'd
rather put up with a warning message than take that risk. YMMV.
What exactly made you beleave OP's implementation might
not document "void main(void)"?

:-)

--
Tor <torust AT online DOT no>

Nov 16 '06 #14

P: n/a
"Tor Rustad" <to********@hotmail.comwrites:
Keith Thompson wrote:
>jaysome <ja*****@spamcop.netwrites:
On Wed, 15 Nov 2006 17:03:39 -0500, CBFalconer <cb********@yahoo.com>
wrote:
jaysome wrote:

Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined)

[...]
>Sure, that makes sense *if* your implementation documents
"void main(void)" as valid declaration for main.

If it doesn't, you're risking undefined behavior. Personally, I'd
rather put up with a warning message than take that risk. YMMV.

What exactly made you beleave OP's implementation might
not document "void main(void)"?

:-)
I believe that it *might* not because I don't know one way or the
other. For the same reason, I believe that it might.

(I see the smiley, but I don't get the joke.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 16 '06 #15

P: n/a
Keith Thompson <ks***@mib.orgwrote:

(From the OP:)
>jaysome wrote:

Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined)
I believe that it *might* not because I don't know one way or the
other. For the same reason, I believe that it might.
OP clearly stated that void main(void) was documented and well-defined
for his freestanding implementation, leaving little room for doubt.

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
Nov 16 '06 #16

P: n/a
Christopher Benson-Manica <at***@norge.freeshell.orgwrites:
Keith Thompson <ks***@mib.orgwrote:
(From the OP:)
>>jaysome wrote:

Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined)
>I believe that it *might* not because I don't know one way or the
other. For the same reason, I believe that it might.

OP clearly stated that void main(void) was documented and well-defined
for his freestanding implementation, leaving little room for doubt.
There's plenty of room for doubt for those of us who don't read
carefully enough. (*sigh*)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 16 '06 #17

P: n/a
On Wed, 15 Nov 2006 23:03:03 -0800, in comp.lang.c , jaysome
<ja*****@spamcop.netwrote:
>Because if I define main() with a return type of int, and I have
something like this:
(example of a main that never returns)
>then some compilers and PC-lint complain about the "return 0;"
statement being unreachable.
"When I drive too fast, the oil light comes on.
So I disconnected the bulb, now it no longer bothers me."
>Using void main(void) is appropriate for most embedded applications
that I can think of.
Indeed, and this is why the rule is specifically for hosted
implementations. Furthermore embedded implementations document this as
an extension.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Nov 16 '06 #18

P: n/a
Keith Thompson wrote:
Christopher Benson-Manica <at***@norge.freeshell.orgwrites:
OP clearly stated that void main(void) was documented and
well-defined for his freestanding implementation, leaving little
room for doubt.

There's plenty of room for doubt for those of us who don't read
carefully enough. (*sigh*)

We gotta start reading the messages now? Damn.


Brian
Nov 16 '06 #19

P: n/a
"Default User" <de***********@yahoo.comwrites:
Keith Thompson wrote:
>Christopher Benson-Manica <at***@norge.freeshell.orgwrites:
OP clearly stated that void main(void) was documented and
well-defined for his freestanding implementation, leaving little
room for doubt.

There's plenty of room for doubt for those of us who don't read
carefully enough. (*sigh*)

We gotta start reading the messages now? Damn.
No, not at all. We just gotta start reading the messages now.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 16 '06 #20

P: n/a
Keith Thompson wrote:
"Default User" <de***********@yahoo.comwrites:
Keith Thompson wrote:
Christopher Benson-Manica <at***@norge.freeshell.orgwrites:
OP clearly stated that void main(void) was documented and
well-defined for his freestanding implementation, leaving little
room for doubt.

There's plenty of room for doubt for those of us who don't read
carefully enough. (*sigh*)
We gotta start reading the messages now? Damn.

No, not at all. We just gotta start reading the messages now.
Oops, too late for me. I missed it.


Brian
Nov 16 '06 #21

P: n/a
Keith Thompson wrote:
"Default User" <de***********@yahoo.comwrites:
Keith Thompson wrote:
Christopher Benson-Manica <at***@norge.freeshell.orgwrites:
OP clearly stated that void main(void) was documented and
well-defined for his freestanding implementation, leaving little
room for doubt.

There's plenty of room for doubt for those of us who don't read
carefully enough. (*sigh*)
We gotta start reading the messages now? Damn.

No, not at all. We just gotta start reading the messages now.
We need volatile-qualified people as well. :-)

--
Tor <torust AT online DOT no>

Nov 16 '06 #22

P: n/a

Tor Rustad wrote:
Keith Thompson wrote:
"Default User" <de***********@yahoo.comwrites:
Keith Thompson wrote:
>Christopher Benson-Manica <at***@norge.freeshell.orgwrites:
OP clearly stated that void main(void) was documented and
well-defined for his freestanding implementation, leaving little
room for doubt.
>>
>There's plenty of room for doubt for those of us who don't read
>carefully enough. (*sigh*)
>
We gotta start reading the messages now? Damn.
No, not at all. We just gotta start reading the messages now.

We need volatile-qualified people as well. :-)
We already have lots of volatile qualified people, though - will they
do instead?

Nov 17 '06 #23

P: n/a
J. J. Farrell wrote:
Tor Rustad wrote:
<snip>
We need volatile-qualified people as well. :-)

We already have lots of volatile qualified people,
though - will they do instead?
We only have volatile-qualified objects. ;-)

--
Tor <torust AT online DOT no>

Nov 17 '06 #24

P: n/a
Tor Rustad wrote:
Keith Thompson wrote:
>>"Default User" <de***********@yahoo.comwrites:
>>>Keith Thompson wrote:

Christopher Benson-Manica <at***@norge.freeshell.orgwrites:

>OP clearly stated that void main(void) was documented and
>well-defined for his freestanding implementation, leaving little
>room for doubt.

There's plenty of room for doubt for those of us who don't read
carefully enough. (*sigh*)

We gotta start reading the messages now? Damn.

No, not at all. We just gotta start reading the messages now.


We need volatile-qualified people as well. :-)
Nah... only volatile people, you dont need to qualify them :)
Nov 17 '06 #25

P: n/a
CBFalconer wrote:
jaysome wrote:

Suppose I have something like this on a free-standing
environment (where void main(void) is documented and well-defined):

void main (void)

Even if it is defined for your peculiar system, why use it? All
you are doing is creating another needless incompatibility.
The system I'm coding on at the moment, does not even
accept int main(void).

Nov 17 '06 #26

P: n/a
In article <ej**********@chessie.cirr.com>,
Christopher Benson-Manica <at***@norge.freeshell.orgwrote:
....
>I believe that it *might* not because I don't know one way or the
other. For the same reason, I believe that it might.

OP clearly stated that void main(void) was documented and well-defined
for his freestanding implementation, leaving little room for doubt.
Such subtleties are generally lost on KT.

Nov 26 '06 #27

This discussion thread is closed

Replies have been disabled for this discussion.