Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 455 Vote(s) - 3.55 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Arithmetic operations between constants

#1
Consider this code;

#define A 5
#define B 3

int difference = A - B;

does value of "difference" is hardcoded as "2" in compile time, or does it get calculated on runtime?
Reply

#2
The standard does not specify this sort of thing. It says nothing about potential optimizations like this (and for good reason. A standard defines semantics, not implementation).

Why not look at the disassembly for your compiler? That will give you a definitive answer.

...

So let's do that.

Here is the output from VC++ 10:

#include <iostream>

#define A 5
#define B 3

int main() {
int x = A - B;
std::cout << x; // make sure the compiler doesn't toss it away
010A1000 mov ecx,dword ptr [__imp_std::cout (10A2048h)]
010A1006 push 2
010A1008 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (10A2044h)]
return 0;
010A100E xor eax,eax

As you can see, it just replaced the occurrence of `x` with a static value of 2 and pushed it onto the stack for the call to `cout`. It did not evaluate the expression at runtime.
Reply

#3
The `A` and `B` macros are a bit of a distraction. This:

#define A 5
#define B 3

int difference = A - B;

is exactly equivalent to this:

int difference = 5 - 3;

so let's discuss the latter.

`5 - 3` is a *constant expression*, which is an expression that "can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be". It's also an *integer constant expression". For example, a case label must be an integer constant expression, so you could write either this:

switch (foo) {
case 2: /* this is a constant */
...
}

or this:

switch (foo) {
case 5 - 3: /* this is a constant expression */
...
}

But note that the definition says that it *can be* evaluated during translation, not that it must be. There are some contexts that require constant expressions, and in those contexts the expression *must* be evaluated at compile time.

But assuming that `difference` is declared inside some function, the initializer is not one of those contexts.

Any compiler worth what you pay for it (even if it's free) will reduce `5 - 3` to `2` at compile time, and generate code that stores the value `2` in `difference`. But it's not required to do so. The C standard specifies the *behavior* of programs; it doesn't specify how that behavior must be implemented. But it's safe to assume that whatever compiler you're using will replace `5 - 3` by `2`.

Even if you write:

int difference = 2;

a compiler could legally generate code that loads the value `5` into a register, subtracts `3` from it, and stores the contents of the register into `difference`. That would be a silly thing to do, but the language standard doesn't exclude it.

As long as the final result is that `difference` has the value `2`, the language standard doesn't care how it's done.

On the other hand, if you write:

switch (foo) {
case 5 - 3: /* ... */
case 2: /* ... */
}

then the compiler *must* compute the result so it can diagnose the error (you can't have two case labels with the same value.

Finally, if you define `difference` at file scope (outside any function), then the initial value *does* have to be constant. But the real distinction in that case is not whether `5 - 3` will be evaluated at compile time, it's whether you're *allowed* to use a non-constant expression.

Reference: The latest draft of the 2011 C standard is [N1570][1] (large PDF); constant expressions are discussed in section 6.6.


[1]:
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through