Topic: Jumping over initialization of a static local variable.
Author: James Kanze <james.kanze@gmail.com>
Date: Fri, 22 Jun 2007 09:51:37 CST Raw View
Two questions, really. First, is the following program legal:
int
main( int argc, char** )
{
switch ( argc ) {
case 0 :
static char const m[] = "toto" ;
break ;
default:
std::cout << m << std::endl ;
break ;
}
}
G++ says yes, VC++ and Sun CC no. The relevant paragraph in the
standard is [stmt.dcl]/2:
It is possible to transfer into a block, but not in a
way that bypasses declarations with initialization. A
program that jumps from a point where a local variable
with automatic storage duration is not in scope to a
point where it is in scope is ill-formed unless the
variable has POD type (3.9) and is declared without an
initializer (8.5).
The first sentence would seem to say that it's illegal; the
second not.
The second question: what happens if I replace the declaration
of m with:
static std::string const m( "toto" ) ;
? I get the same responses from the three compilers: g++
accepts it, but VC++ and Sun CC don't. The program generated by
g++ not surprisingly core dumps, however.
An ancillary question would be: what should the standard say? I
rather think that there should be no problem jumping over static
initialization, as in the first example, but I don't like g++'s
behavior in the second case, with std::string.
(Should we put up a defect report on this?)
--
James Kanze (GABI Software, from CAI) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 22 Jun 2007 15:44:45 GMT Raw View
James Kanze wrote:
> Two questions, really. First, is the following program legal:
> int main( int argc, char** ) {
> switch ( argc ) {
> case 0 : static char const m[] = "toto" ; break ;
> default: std::cout << m << std::endl ; break ;
> }
> }
>
> The relevant paragraph in the standard is [stmt.dcl]/2:
>
> It is possible to transfer into a block, but not in a
> way that bypasses declarations with initialization.
And the program does that, so it's not legal.
> A program that jumps from a point where a local variable
> with automatic storage duration is not in scope to a
> point where it is in scope is ill-formed unless the
> variable has POD type (3.9) and is declared without an
> initializer (8.5).
Your program has no such jumps, so this sentence doesn't apply
to your program. There's no contradiction here. The first sentence
prohibits jumping past variables declared with initializers. The
second sentence permits jumping over certain automatic variables
declared without initializers.
A slightly more interesting question is what happens when the
static variable declaration is just
static std::string const m;
You may be allowed to jump over that, since neither sentence seems
to prohibit it. But since its constructor won't run until control
passes through the declaration, you're constrained by [basic.life]
as to how you may use it. On the other hand, [dcl.init]/9 says
If no initializer is specified for an object, and the
object is of (possibly cv-qualified) non-POD class type
(or array thereof), the object shall be default-initialized
so maybe the static string qualifies as a "declaration with
initialization" even though there's no initializer, and then you
wouldn't be allowed to jump over it.
It would make more sense for "with automatic storage duration" to be
removed from the paragraph, though. But maybe someone uses code like
this?
switch (n) case 0: static string m; default: m += '.';
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: ricecake@gehennom.invalid (Marcus Kwok)
Date: Fri, 22 Jun 2007 11:58:02 CST Raw View
James Kanze <james.kanze@gmail.com> wrote:
> Two questions, really. First, is the following program legal:
>
> int
> main( int argc, char** )
> {
> switch ( argc ) {
> case 0 :
> static char const m[] = "toto" ;
> break ;
>
> default:
> std::cout << m << std::endl ;
> break ;
> }
> }
>
> G++ says yes, VC++ and Sun CC no.
Just as another data point, Comeau Online also accepts it.
> The second question: what happens if I replace the declaration
> of m with:
> static std::string const m( "toto" ) ;
> ? I get the same responses from the three compilers: g++
> accepts it, but VC++ and Sun CC don't. The program generated by
> g++ not surprisingly core dumps, however.
Comeau Online also accepts the std::string version as well.
--
Marcus Kwok
Replace 'invalid' with 'net' to reply
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Gennaro Prota <invalid@yahoo.com>
Date: Sat, 23 Jun 2007 09:25:05 CST Raw View
James Kanze wrote:
> Two questions, really. First, is the following program legal:
>
> int
> main( int argc, char** )
> {
> switch ( argc ) {
> case 0 :
> static char const m[] = "toto" ;
> break ;
>
> default:
> std::cout << m << std::endl ;
> break ;
> }
> }
>
> G++ says yes, VC++ and Sun CC no. The relevant paragraph in the
> standard is [stmt.dcl]/2:
>
> It is possible to transfer into a block, but not in a
> way that bypasses declarations with initialization. A
> program that jumps from a point where a local variable
> with automatic storage duration is not in scope to a
> point where it is in scope is ill-formed unless the
> variable has POD type (3.9) and is declared without an
> initializer (8.5).
>
> The first sentence would seem to say that it's illegal; the
> second not.
>
> The second question: what happens if I replace the declaration
> of m with:
> static std::string const m( "toto" ) ;
> ? I get the same responses from the three compilers: g++
> accepts it, but VC++ and Sun CC don't. The program generated by
> g++ not surprisingly core dumps, however.
>
> An ancillary question would be: what should the standard say? I
> rather think that there should be no problem jumping over static
> initialization, as in the first example, but I don't like g++'s
> behavior in the second case, with std::string.
>
> (Should we put up a defect report on this?)
My take is that the intent is for both versions to be legal. That's
what I find reasonable to assume when I consider the response to core
issue 467. However Hyman pointed out at least one different
interpretation (the word "jump" is probably a little too ambiguous),
so it might be worth to put up a small DR and ask for clearer wording.
My two cents.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "James Kanze" <james.kanze@gmail.com>
Date: Thu, 25 Jan 2007 12:46:41 CST Raw View
I'm wondering about the restrictions concerning jumping past a
static initializer. According to [stmt.dcl]/3:
It is possible to transfer into a block, but not in a
way that bypasses declarations with initialization. A
program that jumps from a point where a local variable
with automatic storage duration is not in scope to a
point where it is in scope is ill-formed unless the
variable has POD type and is declared without an
initializer.
In my mind, this raises several questions:
-- Static initialization doesn't seem to be exempt. I first
encountered the problem with something like:
switch ( x ) {
case 0 :
static char const m[] = "toto" ;
f( toto ) ;
break ;
default:
break ;
}
VC++ objected, after the code had successfully passed g++
and Sun CC, but on careful reading of the standard, VC++ is
correct, and the other two no (depending on the resolution
of the following point). Never the less, it would seem
reasonable to me to allow this.
-- The first sentence says that initialization cannot be
bypassed, the second only speaks about variables with
automatic storage duration. It would seem obvious to me,
however, that variables with static storage duration should
also be included, at least if they have non-static
initialization. Otherwise, given something like:
goto foo ;
while ( condition ) {
static MyClassWithNonTrivialCtor localStatic ;
foo:
// And what's with localStatic here?
}
The first sentence quoted above suggests that this is
illegal; the second seems to say no.
This second point sure looks like a defect to me; if so,
correcting it could give us a possibility to "adjust" the first
step to what I (and others?) would expect. Might I suggest the
following wording (one additional sentence added at the end):
It is possible to transfer into a block, but not in a
way that bypasses declarations with initialization. A
program that jumps from a point where a local variable
with automatic storage duration is not in scope to a
point where it is in scope is ill-formed unless the
variable has POD type and is declared without an
initializer. A program which jumps from a point where a
local variable with static storage duration is not in
scope to a point where it is in scope is ill-formed
unless the variable is of POD type and either has no
declared initialization, or is initialized entirely with
constant expressions.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: gennaro.prota@yahoo.com (Gennaro Prota)
Date: Thu, 25 Jan 2007 20:36:13 GMT Raw View
On Thu, 25 Jan 2007 12:46:41 CST, James Kanze wrote:
>I'm wondering about the restrictions concerning jumping past a
>static initializer. According to [stmt.dcl]/3:
>
> It is possible to transfer into a block, but not in a
> way that bypasses declarations with initialization. A
> program that jumps from a point where a local variable
> with automatic storage duration is not in scope to a
> point where it is in scope is ill-formed unless the
> variable has POD type and is declared without an
> initializer.
>
>In my mind, this raises several questions:
>
> -- Static initialization doesn't seem to be exempt. I first
> encountered the problem with something like:
Hi James, I didn't have time to read all your post, sorry for that,
but surely your question looked like a deja vu, so I looked it up.
This is core issue 467.
PS: I promise to look into your query further :-)
HELP: many of this group's participants might know that I'm the legit owner of
~~~~ the yahoo account with id 'gennaro_prota'; I'd be immensely grateful to
anyone who might help me gaining access to it again (note that I'm now
using the id 'gennaro.prota'). Thanks!
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]