[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::decc

Title:DECC
Notice:General DEC C discussions
Moderator:TLE::D_SMITHNTE
Created:Fri Nov 13 1992
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:2212
Total number of notes:11045

1902.0. "an inconsistency of ADDRCONSTEXT logic?" by STAR::PCLARK () Thu Aug 15 1996 14:15

T.RTitleUserPersonal
Name
DateLines
1902.1ANSI says you can'tDECC::VOGELFri Aug 16 1996 12:1122
1902.2Why does the standard not allow this?SMAUG::GARRODIBM Interconnect EngineeringWed May 07 1997 18:2258
    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.3DECC::VOGELWed May 07 1997 21:5512
    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.4DECC::VMCCUTCHEONThu May 08 1997 09:5231
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.5SPECXN::DERAMODan D'EramoThu May 08 1997 12:5645
	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.6Thanks for the explanationsEDSCLU::GARRODIBM Interconnect EngineeringThu May 08 1997 16:3422
    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.7Why it's not in StandardDECCXL::RMEYERSRandy MeyersThu May 08 1997 16:4329
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.8SPECXN::DERAMODan D'EramoThu May 08 1997 17:1837
	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