T.R | Title | User | Personal Name | Date | Lines |
---|
1902.1 | ANSI says you can't | DECC::VOGEL | | Fri Aug 16 1996 12:11 | 22 |
1902.2 | Why does the standard not allow this? | SMAUG::GARROD | IBM Interconnect Engineering | Wed May 07 1997 18:22 | 58 |
| I too have run into this. I've used Altavista/COMET to find various
talk on this issue in various places and what I've found is that indeed
DECC seems to be following the letter of the ANSI standard. What I
don't understand is:
a) Why does the standard allow simple auto variables to be run time
initialized to non static addresses but DOES NOT allow the exact same
variable inside an auto structure to be initialized to non statoc
addresses.
b) I agree that DECC should follow this standard with /STANDARD=ANSI.
But how about not issuing the waring with the default
/STANDARD=RELAXED_ANSI?
It strikes mer that if the compiler is smart enough to handle these
type of initializations (which it is) it serves no purpose to generate
a WARNING message in anything other than very struct ANSI mode.
As an aside I was wondering whether the reason the standard specified
this restriction is because of a presumed implementation where an
it assumes an initializer of {a, b, c, d, e} would be stored at
compile time in some static storage and just simply moved to the
variable at run time.
I notice that it is not just structures that don't allow this sort of
initialization. It appears that arrays don't either ie in:
main ()
{
int aa, bb, cc, dd, ee;
int *z = &aa;
int *a[5] = {&aa, &bb, &cc, &dd, &ee};
return 1;
}
the compiler is happy to initialize z but not a[].
So in summary does anybody know:
a) Why the standard has this restriction?
b) Why DECC can't not impose this restriction with /RELAXED_ANSI mode?
I got around the problem by throwing
#pragma message save
#pragma message disable ADDRCONSTEXT
...
#pragma message restore
around the code the compiler didn't like. But I don't like using
pragmas because if you port the code you end up having to often ifdef
them out and then some compilers will still moan about them. I'm
religious about not allowing any INFO or WARNING messages to be
generated in code I write. I feel that once you say "well that doesn't
matter", more and more are allowed to appear and then maintainers don't
see real errors because they get lost in the noise.
Dave
|
1902.3 | | DECC::VOGEL | | Wed May 07 1997 21:55 | 12 |
|
Dave,
I'm afraid I can not answer your first question, but I do agree
with you concerning your second question. We'll see what
we can do to remove this warning in relaxed_ansi mode.
Also, you can also work around the problem by using
/WARN=DISABLE=ADDRCONSTEXT when invoking the compiler.
Ed
|
1902.4 | | DECC::VMCCUTCHEON | | Thu May 08 1997 09:52 | 31 |
| I found the following text in the rational which
seems to help explain things a little bit.
"The Committee considered proposals for
permitting automatic aggregate initialization
to consist of a brace-enclosed series of
arbitrary (execute-time) expressions,
instead of just those usable for a translate-time
static initializer. However, cases like this
were troubling:
int x[2] = {f(x[1]), f(x[0])};
Rather than determine a set of cases which
would avoid pathological cases and yet not
seem too arbitrary, the Committee elected to
permit only static initializers..."
It sort of sounds like they basically agreed that
what you are trying to do IS useful, but somehow
they did not feel comfortable describing the set
of run-time expressions that were safe.
IF you move the initializations out to file scope,
of course then it would be allowed, because
aa, bb, cc, dd, ee would not be on main's stack.
I will ask our standards expert if he can provide
a more complete answer.
--val
|
1902.5 | | SPECXN::DERAMO | Dan D'Eramo | Thu May 08 1997 12:56 | 45 |
| re .2
> I got around the problem by throwing
>
> #pragma message save
> #pragma message disable ADDRCONSTEXT
> ...
> #pragma message restore
>
> around the code the compiler didn't like. But I don't like using
> pragmas because if you port the code you end up having to often ifdef
> them out and then some compilers will still moan about them.
It's worse than that...if you port the code the target
compiler might consider the initializer list to be an error
instead of just something to warn about.
So the cleanest approach is to forget the pragmas and just
change the code to stick to the letter of the standard.
For a structure or union, you can use for example
struct X { int a; int b; int c; };
struct X makeX(int a, int b, int c);
void f(int a, int b, int c)
{
struct X x = makeX(a, b, c); /* not struct X x = { a, b, c }; */
}
I.e., it is only stuff in an initializer *list* that must be
constant, a function call as the entire initializer is okay.
You can't do this for an array because a function cannot return
an array. (You can do this for a structure or union containing
an array though.) So you aren't always limited to
x.a = a;
x.b = b;
x.c = c;
(makeX will have to be defined that way, but everywhere else
you can just call makeX).
Dan
|
1902.6 | Thanks for the explanations | EDSCLU::GARROD | IBM Interconnect Engineering | Thu May 08 1997 16:34 | 22 |
| Re .-2
Thanks for the explanation from the standard. I expected it was
something like that.
Re .-1
The code giving me the error is in the $DESCRIPTOR macro defined by
the system require file descrip.h so it is that that would need to
be fixed or I just shouldn't use it.
I agree that my pragma hack is not a good way around this. I think
the best solution overall is for DECC not to give an error in
RELAXED_ANSI mode if it actually does manage to successfully generate
code to do this rumtime initialization. Of course if it is one of the
pathological cases (rare) that the committee was worried about and the
compiler can't reliably generate absolute correct code for that
specific case then of course it should give an error regardless.
Dave, A 'reformed' BLISS programmer who "C" is growing on. But I still
greatly miss the powerful BLISS macro facility.
|
1902.7 | Why it's not in Standard | DECCXL::RMEYERS | Randy Meyers | Thu May 08 1997 16:43 | 29 |
| Reply .4 does explain why the ANSI C committee decided to just make
the case invalid: the committee was too lazy or too timid to define
the evaluation order and sequence points for an initializer.
Consider:
int i = 0;
int a[2] = {i++, i++};
Depending on how you write the rules, the array might be initialized
with:
{0, 1} /* Left to right evaluation with sequence point */
or
{1, 0} /* Right to left evaluation with sequence point */
Or, the committee might decide not to define a sequence point inside
the initializer braces (this sort of thing sometimes allows compilers
to generate better code). In such a case the above initializer would
be invalid and non-portable, just like (i++ + i++). That would allow
compilers to also initialize the array with:
{0, 0}
{1, 1}
because the compiler would not be obligated to notice that one of comma
separated initializer expressions might interfere with the evaluation of
a different initializer expression. In effect, the code for the initializer
expressions could be evaluated in parallel or in an interleaved fashion.
|
1902.8 | | SPECXN::DERAMO | Dan D'Eramo | Thu May 08 1997 17:18 | 37 |
| re .6
> The code giving me the error is in the $DESCRIPTOR macro defined by
> the system require file descrip.h so it is that that would need to
> be fixed or I just shouldn't use it.
That makes it less likely that the code will be ported to a
non OpenVMS system and more likely that your #pragma's are
okay. :-)
You can also change the $DESCRIPTOR macro or add a new macro
for non-static descriptor declarations
#define AUTO_DESCRIPTOR(name, string) \
struct dsc$descriptor_s name = \
make_fixed_length_string_descriptor(sizeof(string)-1, string)
along with a new function
struct dsc$descriptor_s
make_fixed_length_string_descriptor(unsigned short n, char *s)
{
struct dsc$descriptor_s dsc;
dsc.dsc$w_length = n;
dsc.dsc$b_dtype = DSC$K_DTYPE_T;
dsc.dsc$b_class = DSC$K_CLASS_S;
dsc.dsc$a_pointer = s;
return dsc;
}
The function can be prototyped (or even statically defined)
in the same header that #define's AUTO_DESCRIPTOR.
Changing $DESCRIPTOR this way of course would break it for
declaring descriptor variables with static storage duration.
Dan
|