Global Variable Access Relative to Function Calls and Returns

旧时模样 提交于 2019-12-06 16:29:58

问题


I have been researching this topic and I can not find a specific authoritative answer. I am hoping that someone very familiar with the C spec can answer - i.e. confirm or refute my assertion, preferably with citation to the spec.

Assertion: If a program consists of more than one compilation unit (separately compiled source file), the compiler must assure that global variables (if modified) are written to memory before any call to a function in another unit or before the return from any function. Also, in any function, the global must be read before its first use. Also after a call of any function, not in the same unit, the global must be read before use. And these things must be true whether the variable is qualified as "volatile" or not because a function in another compilation unit (source file) could access the variable without the compiler's knowledge. Otherwise, "volatile" would always be required for global variables - i.e. non-volatile globals would have no purpose.

Could the compiler treat functions in the same compilation unit differently than ones that aren't? All of the discussions I have found for the "volatile" qualifier on globals show all functions in the same compilation unit.

Edit: The compiler cannot know whether functions in other units use the global or not. Therefore I am assuming the above conditions.

I found these two other questions with information related to this topic but they don't address it head on or they give information that I find suspect:

Are global variables refreshed between function calls?

When do I need to use volatile in ISRs?


回答1:


[..] in any function, the global must be read before its first use.

Definitely not:

static int variable;
void foo(void) {
  variable = 42;
}

Why should the compiler bother generating code to read the variable?

The compiler must assure that global variables are written to memory before any function call or before the return from a function.

No, why should it?

void bar(void) {
   return;
}
void baz(void) {
  variable = 42;
  bar();
}

bar is a pure function (should be determinable for a decent compiler), so there's no chance of getting any different behaviour when writing to memory after the function call.

The case of "before returning from a function" is tricky, though. But I think the general statement ("must") is false if we count inlined (static) functions, too.

Could the compiler treat functions in the same compilation unit differently than ones that aren't?

Yes, I think so: for a static function (whose address is never taken) the compiler knows exactly how it is used, and this information could be used to apply some more radical optimisations.

I'm basing all of the above on the C version of the As-If rule, specified in §5.1.2.3/6 (N1570):

The least requirements on a conforming implementation are:

  • Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine.

  • At program termination, all data written into files shall be identical to the result that execution of the program according to the abstract semantics would have produced.

  • The input and output dynamics of interactive devices shall take place as specied in 7.21.3. The intent of these requirements is that unbuffered or line-buffered output appear as soon as possible, to ensure that prompting messages actually appear prior to a program waiting for input.

This is theobservable behaviorof the program.

In particular, you might want to read the following "EXAMPLE 1".



来源:https://stackoverflow.com/questions/39416426/global-variable-access-relative-to-function-calls-and-returns

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!