Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: A question on variable scope, coming from a relative beginner |
| Date | 2015-11-13 08:33 -0500 |
| Organization | A noiseless patient Spider |
| Message-ID | <n24om3$5sb$1@dont-email.me> (permalink) |
| References | <n230ii$pmi$1@news.albasani.net> <n231rp$qc0$1@dont-email.me> <n23j1m$cad$1@news.albasani.net> <n23knc$l07$1@dont-email.me> <n23ukh$vb5$1@news.albasani.net> |
On 11/13/2015 01:05 AM, Jon Rossen wrote: > James, thanks for all this info; there is lots of stuff here to > digest...Comments below inline -jonR > > On 11/12/2015 7:19 PM, James Kuyper wrote: ... >> things. The static keyword has been given three entirely unrelated >> meanings, depending upon the context: > > Ok, great. It's good to know that the reason I think it's screwed up is > because I am starting to learn it accurately...particularly with respect > to the fact that the different aspects of the feature aren't related to > each other. > >> >> 1. When applied to the definition of a file scope object or function, it >> gives that object or function's identifier internal linkage. (6.2.2p3) >> >> 2. When applied to the definition of a block scope object, it gives that >> object static storage duration.(6.2.4p3) >> >> 3. When used inside the leading dimension of a function parameter >> declared as if it were an array, as in the following example: >> >> void func(int param[static 16]) >> >> it makes it undefined behavior to call func() with a pointer to that >> does not give access to an array containing at least 16 items. >> (6.7.6.3p7). This is a relatively new meaning, introduced in C99. > > I'm not sure I understand all of this yet. Btw, to give me a headstart > or to cheat a bit, how do the two aspects of static that I mentioned (a) > persistent values with local variables That's "static storage duration". What that means is that the variable storage exists from the start of the program to the very end of the program, so what you stored in it at one time is still there the next time you look at it. All file scope objects have static storage duration; other objects have static storage duration only if declared 'static'. The most common alternative is "automatic storage duration", which applies to function parameters and all objects defined inside of functions, unless declared 'static'. These object have storage with a lifetime that starts when control enters the block where they are defined, and ends when the block is exited (for function parameters, the relevant block is the outermost block of the function). Each time the lifetime of an object starts, it's a new object, which might be located at a different address than the previous time. If an initializer is provided, it gets initialized to the specified value each time (unless control jumps into the block at some point after the initialization using switch, goto or longjmp()) - otherwise, the object's value is uninitialized. Either way, any value stored in it during a previous lifetime was lost when that lifetime ended. There's also thread storage duration, which is new in C2011, which applies to objects declared _Thread_local - their lifetime begins and ends with the creation and destruction of the corresponding thread. The other option is dynamic storage duration, which applies to dynamically allocated objects, which are created by a call to malloc(), calloc() or realloc(), and can be destroyed by a call to free() or realloc(). & b) disallowing the use of an > external variable to be used in another module correlate to the 3 > examples you gave above. That's internal linkage. Being available from other modules is external linkage. > ... As I said, I don't really fully understand > this stuff yet. Btw, are those section/page sections you are pointing > out at the end of your paragraphs? If so, to what publication? The current C standard, C2011. If you google for n1570.pdf, you can get a free copy that is almost identical to the finally approved standard. If you'd like to pay huge sums of money, you can get a copy of the final standard from ISO, or from your country's own standards organization, assuming that it's a member of ISO. ... >>> 2. Ok, using extern in other modules to access the originally defined >>> variable. I understand this and how extern allows you to declare the >>> existence of a previously *defined* variable. However, I'm seeing >>> inconsistencies in the need to use extern for this purpose. I'm >>> referring to differences between 3 different compilers that are in 3 >>> different IDEs that I'm using: Visual Studio 2010, Code::Blocks and >>> Xcode (yes, I'm working on Objective-C too). In both of these examples >>> I've created a bare-bones C project with two modules. So, I've got >>> main.c and 2.c. I have a variable defined in main.c that's not inside >>> any function; let's call it int foo. In module 2.c, in theory I am >>> supposed to use 'extern int foo' in order to access that variable. >>> However, in Visual Studio and Code::Blocks I don't have to use 'extern'. >>> All I have to do is use the statement 'int foo' at the beginning of >>> the module, before any dependent functions and I can access the >>> originally defined int foo in main.c (the first module). The use of >>> extern is *not* necessary. ... >> >> What you've done there is create two separate external definitions for >> the same exact identifier, one in each translation unit. >> >> "If an identifier declared with external linkage is used in an >> expression (other than as part of the operand of a sizeof or >> _Alignof operator whose result is an integer constant), somewhere in the >> entire program there shall be exactly one external definition for the >> identifier; otherwise, there shall be no more than one." >> >> Code containing two external definitions for the same identifier >> violates a "shall" that occurs outside a constraints section. The >> behavior of such a program is undefined (4p6). "undefined behavior" only >> means that the C standard does not impose any requirements on the >> behavior. In particular, it does not require that your implementation >> give you any error messages. Because there are no requirements, Visual >> Studio is free to translate your program any way it wants. What it >> apparently wants to do is to merge the external definitions from your >> two different translation units, and treat them as the same object. This >> is actually a fairly popular choice. Personally, I'd prefer an error >> message. > > Ok, thanks for the explanation; I find it interesting. It does seem > contradictory, unless I'm not fully understanding the discussion you are > presenting. It's called 'undefined behavior' which means that the C > standard doesn't impose any requirements on the behavior. Why then does > the language then have 'extern' which seems to want to make this > orderly? You would think since 'extern' exists, there would be > requirements for this. The purpose of 'extern' is to give such code defined behavior. Declarations containing 'extern' are NOT definitions. Therefore, if you put 'extern' on all but one of the declarations, everything is fine. C requires you to identify which one is the actual definition; the others are just references to the actual definition. It would certainly be feasible to require that all such definitions be merged, but the committee decided not to impose such a requirement - at the time when that decision was made, it would have been excessively burdensome on some platforms. >>> ... I get the correct results. In Xcode it is >>> necessary, and not using extern causes linker errors...duplicate symbols >>> or something to that extent. That makes sense as technically I'm >>> incorrectly declaring int foo two times by not using extern for the >>> second time. So, why do Visual Studio and Code:Blocks allow me to do >>> this, I get the correct result, and there are no linker errors for both >>> of these IDEs? >> >> Since the C standard imposes no requirements on the behavior of such a >> program, the way that Code:Blocks deals with this code is just as >> acceptable as the way that Visual Studios does. >> > > Ok, just to make sure we're on the same page, I did state that Visual > Studio and Code::Blocks both work the same way with respect to > this..well maybe completely under the hood but the end results are the > same. So, you are saying that VS and C::B are both acceptable. I guess > since you stated you would prefer an error message, you would favor the > behavior of Xcode which put up a linker error message. That was a mistake on my part. If I'd read your paragraph a little more carefully, I would have mentioned all three compilers. -- James Kuyper
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
A question on variable scope, coming from a relative beginner Jon Rossen <jonr17@comcast.net> - 2015-11-12 13:32 -0800
Re: A question on variable scope, coming from a relative beginner John Gordon <gordon@panix.com> - 2015-11-12 21:57 +0000
Re: A question on variable scope, coming from a relative beginner Jon Rossen <jonr17@comcast.net> - 2015-11-12 16:06 -0800
Re: A question on variable scope, coming from a relative beginner James Kuyper <jameskuyper@verizon.net> - 2015-11-12 19:33 -0500
Re: A question on variable scope, coming from a relative beginner Jon Rossen <jonr17@comcast.net> - 2015-11-12 20:22 -0800
Re: A question on variable scope, coming from a relative beginner James Kuyper <jameskuyper@verizon.net> - 2015-11-13 08:08 -0500
Re: A question on variable scope, coming from a relative beginner Richard Heathfield <rjh@cpax.org.uk> - 2015-11-12 21:57 +0000
Re: A question on variable scope, coming from a relative beginner Jon Rossen <jonr17@comcast.net> - 2015-11-12 18:47 -0800
Re: A question on variable scope, coming from a relative beginner James Kuyper <jameskuyper@verizon.net> - 2015-11-12 22:19 -0500
Re: A question on variable scope, coming from a relative beginner Jon Rossen <jonr17@comcast.net> - 2015-11-12 22:05 -0800
Re: A question on variable scope, coming from a relative beginner Richard Heathfield <rjh@cpax.org.uk> - 2015-11-13 07:10 +0000
Re: A question on variable scope, coming from a relative beginner James Kuyper <jameskuyper@verizon.net> - 2015-11-13 08:33 -0500
Re: A question on variable scope, coming from a relative beginner Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-13 12:24 -0800
Re: A question on variable scope, coming from a relative beginner Keith Thompson <kst-u@mib.org> - 2015-11-14 11:58 -0800
Re: A question on variable scope, coming from a relative beginner James Kuyper <jameskuyper@verizon.net> - 2015-11-14 15:27 -0500
Re: A question on variable scope, coming from a relative beginner Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-12 14:00 -0800
Re: A question on variable scope, coming from a relative beginner Richard Heathfield <rjh@cpax.org.uk> - 2015-11-12 23:55 +0000
Re: A question on variable scope, coming from a relative beginner Keith Thompson <kst-u@mib.org> - 2015-11-12 17:11 -0800
Re: A question on variable scope, coming from a relative beginner Jon Rossen <jonr17@comcast.net> - 2015-11-12 20:39 -0800
Re: A question on variable scope, coming from a relative beginner Jon Rossen <jonr17@comcast.net> - 2015-11-12 20:38 -0800
Re: A question on variable scope, coming from a relative beginner Keith Thompson <kst-u@mib.org> - 2015-11-12 22:13 -0800
Re: A question on variable scope, coming from a relative beginner Jon Rossen <jonr17@comcast.net> - 2015-11-15 21:17 -0800
csiph-web