public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: "gcc" complains about a constant being non constant...(sorry  for dup)
@ 2009-07-06 10:56 Bill McEnaney
  2009-07-06 19:13 ` "gcc" complains about a constant being non constant Linda A. Walsh
  0 siblings, 1 reply; 8+ messages in thread
From: Bill McEnaney @ 2009-07-06 10:56 UTC (permalink / raw)
  To: Andrew Haley, Linda A. Walsh, gcc-help

Maybe we need to distinguish between a const variable and a literal.

> Linda A. Walsh wrote:
> > (Sorry if this is a dup, somehow my from address got mangled with
the from
> > addr having this message being sent from my system's MAILER DAEMON! 
> > Weird.)
> > 
> > I have a "proglet", included below (twice, in fact! :-), first with line
> > numbering for referring to the error messages, and a 2nd time without
> > line numbers to allow for easy cut & pasting to try it in your local
> > environment.
> > 
> > The error output appears to indicate a problem with compile-time
constant
> > folding.
> > 
> > gcc --version shows:
> > gcc (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]
> > 
> > Compile time output:
> > ct.c:10: error: initializer element is not constant
> > ct.c:11: error: initializer element is not constant
> > 
> > Here's the proglet w/line numbering for reference:
> > ------
> > 1 #include <stdio.h>
> > 2 #include <stdlib.h>
> > 3 #include <strings.h>
> > 4  5 typedef const char * String;
> > 6  7 static const String days [] ={"Sun", "Mon", "Tue", "Wed", "Thu" ,
> > "Fri", "Sat"};
> > 8 static const int sizeof_days            = sizeof(days);
> > 9 static const int sizeof_String          = sizeof(String);
> > 10 static const int numdays                = sizeof_days /
sizeof_String;
> > 11 static const int last_index=numdays-1;
> > 12 13 int main (){
> > 14         printf("numdays=%d, lastidx=%d\n",numdays,last_index);
> > 15 }
> > --------
> > 
> > if, in line 8, sizeof(days) is a constant,  AND in line 9,
> > sizeof(String) is
> > a constant, then how can their division (in line 10) NOT be a constant?
> 
> Simple: sizeof(days) is a constant, but sizeof_days is not.  Reason:
because
> the C language standard says so.  A const variable is not a constant.
 It'd be
> nice if it were.
> 
> Andrew.
> 
> 

________________________________________________________________
Please visit a saintly hero:
http://www.jakemoore.org

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "gcc" complains about a constant being non constant...
  2009-07-06 10:56 "gcc" complains about a constant being non constant...(sorry for dup) Bill McEnaney
@ 2009-07-06 19:13 ` Linda A. Walsh
  2009-07-08  9:03   ` Andrew Haley
  0 siblings, 1 reply; 8+ messages in thread
From: Linda A. Walsh @ 2009-07-06 19:13 UTC (permalink / raw)
  To: Bill McEnaney; +Cc: Andrew Haley, gcc-help





Bill McEnaney wrote:
> Maybe we need to distinguish between a const variable and a literal.
>>> if, in line 8, sizeof(days) is a constant,  AND in line 9,
>>> sizeof(String) is
>>> a constant, then how can their division (in line 10) NOT be a constant?
>> Simple: sizeof(days) is a constant, but sizeof_days is not.  Reason:
> because
>> the C language standard says so.  A const variable is not a constant.
>  It'd be
---
    Sorry to say, but whoever the 'rocket scientist' that thought up
this nonsense was, should be shot.

I can use sizeof(days)/sizeof(String)-1 as a direct initializer into
a 'const' variable -- and THAT works:
typedef const char * String;

static const String suffixes [] = {"B", "KB", "MB", "GB", "TB"};

static const int index_of_last_suffix = sizeof(suffixes)/(sizeof 
(String)) - 1;

As long as I don't try to assign "sizeof(suffixes)/sizeof(String) to
a 'const' declared integer, first, and then use that as an intermediate
step, I'm fine.  But If I want to first assign the quotient to a const int
for 'num_items', and then use that value with "-1" to init a 2nd 
constant, it fails.

Sure seems like a C-design bug -- i.e. may be designed that way, but
it's certainly non-intuitive to see
const int a=b/c;
const int d=a-1; FAIL, while
const int d=b/c-1; works

Certainly breaks or voids the concept of equivalent expressions being
equal.

Do I remember incorrectly, or is this fixed in C++?

Maybe it should be 'fixed' in gnu-c unless they are running under strict
POSIX-anal-retentive mode?  ;^)

Sigh...

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "gcc" complains about a constant being non constant...
  2009-07-06 19:13 ` "gcc" complains about a constant being non constant Linda A. Walsh
@ 2009-07-08  9:03   ` Andrew Haley
  2009-07-10 21:53     ` Linda A. Walsh
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Haley @ 2009-07-08  9:03 UTC (permalink / raw)
  To: Linda A. Walsh; +Cc: Bill McEnaney, gcc-help

Linda A. Walsh wrote:
> 
> Bill McEnaney wrote:
>> Maybe we need to distinguish between a const variable and a literal.

That would IMO be a mistake.  We should use the ISO terminology, which
is "constant expression".

>>>> if, in line 8, sizeof(days) is a constant,  AND in line 9,
>>>> sizeof(String) is
>>>> a constant, then how can their division (in line 10) NOT be a constant?
>>> Simple: sizeof(days) is a constant, but sizeof_days is not.  Reason:
>> because
>>> the C language standard says so.  A const variable is not a constant.
>>  It'd be
> ---
>    Sorry to say, but whoever the 'rocket scientist' that thought up
> this nonsense was, should be shot.

Gosh, I hate sentences that begin "Sorry, but ..."   :-)

> I can use sizeof(days)/sizeof(String)-1 as a direct initializer into
> a 'const' variable -- and THAT works:
> typedef const char * String;
> 
> static const String suffixes [] = {"B", "KB", "MB", "GB", "TB"};
> 
> static const int index_of_last_suffix = sizeof(suffixes)/(sizeof
> (String)) - 1;
> 
> As long as I don't try to assign "sizeof(suffixes)/sizeof(String) to
> a 'const' declared integer, first, and then use that as an intermediate
> step, I'm fine.  But If I want to first assign the quotient to a const int
> for 'num_items', and then use that value with "-1" to init a 2nd
> constant, it fails.
> 
> Sure seems like a C-design bug -- i.e. may be designed that way, but
> it's certainly non-intuitive to see

> const int a=b/c;
> const int d=a-1; FAIL, while
> const int d=b/c-1; works
> 
> Certainly breaks or voids the concept of equivalent expressions being
> equal.

But they're not equivalent.

The key thing to remember here:

    A const variable is not a constant.

const in C is just a type qualifier.

If there's one thing wrong here, it's that const is badly named: it really
means "readonly".

> Do I remember incorrectly, or is this fixed in C++?

Yes, it is different in C++.

Here's the C definition:

"An integer constant expression shall have integer type and shall
only have operands that are integer constants, enumeration constants,
character constants, sizeof expressions whose results are integer
constants, and floating constants that are the immediate operands of
casts. Cast operators in an integer constant expression shall only
convert arithmetic types to integer types, except as part of an
operand to the sizeof operator."

and the C++ definition:

"An integral constant-expression can involve only literals (2.13),
enumerators, const variables or static data members of integral or
enumeration types initialized with constant expressions (8.5),
non-type template parameters of integral or enumeration types, and
sizeof expressions. Floating literals (2.13.3) can appear only if they
are cast to integral or enumeration types. Only type conversions to
integral or enumeration types can be used. In particular, except in
sizeof expressions, functions, class objects, pointers, or references
shall not be used, and assignment, increment, decrement,
function-call, or comma operators shall not be used."

Andrew.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "gcc" complains about a constant being non constant...
  2009-07-08  9:03   ` Andrew Haley
@ 2009-07-10 21:53     ` Linda A. Walsh
  2009-07-11  0:53       ` Ian Lance Taylor
  0 siblings, 1 reply; 8+ messages in thread
From: Linda A. Walsh @ 2009-07-10 21:53 UTC (permalink / raw)
  To: Andrew Haley; +Cc: Bill McEnaney, gcc-help

Andrew Haley wrote:
> Linda A. Walsh wrote:
>> Certainly breaks or voids the concept of equivalent expressions being
>> equal.
> 
> But they're not equivalent.
> The key thing to remember here:
>     A const variable is not a constant.
> const in C is just a type qualifier.
----
	You are right -- However, The C Compiler still could do better.
It's not a bug, but would be an RFE in my circumstance.

	The reason is that all of my 'const inst' were formed from
Pre-processor known values (none really came from actual runtime computed
data.

	I rewrote the program to make it more clear about what the
improvement could have been.  I wasn't misunderstanding the word const
(though I could see my meaning was unclear) -- I was using it also as
a descriptive element to remind me that everything that fed into it
came from compile-time constants.  

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

/* start with assumptions true */
/* Note on abbreviations used in defines:
 * Ar   = Array
 * Asigd= Assigned
 * Bltn = Builtin
 * others, I hope are obvious */

#define PreProc_Groks_sizeof_ConstLenAr_div_sizeof_BltnType_min_one_is_Const 1
#define PreProc_Groks_sizeof_BltnType_AsigdTo_const_int_is_const 0
#define PreProc_Groks_sizeof_ConstLenAr_AsigdTo_const_int_is_const 0
#define PreProc_Groks_const_ints_as_const 1

static const const char * days [] ={
    "Sun", "Mon", "Tue", "Wed", "Thu" , "Fri", "Sat"};

#if PreProc_Groks_sizeof_ConstLenAr_div_sizeof_BltnType_min_one_is_Const
static const int last_index     = sizeof(days) / sizeof(const char *)-1;
#endif


#if PreProc_Groks_sizeof_BltnType_AsigdTo_const_int_is_const
static const int szof_charptr   = sizeof(const char *); 
#endif

#if PreProc_Groks_sizeof_ConstLenAr_AsigdTo_const_int_is_const
static const int szof_days      = sizeof(days);
#endif
    

#if PreProc_Groks_sizeof_BltnType_AsigdTo_const_int_is_const
static const int sizeof_charptr = (const) szof_charptr;
#endif
#if PreProc_Groks_sizeof_ConstLenAr_AsigdTo_const_int_is_const
static const int sizeof_days    = (const) szof_days;
#endif

static const int num_days       = (const) sizeof(days) / sizeof(const char *);

/* fundamental issue boils down to this: PreProc does not understand consts
 * assigned values that are only constants determined at Pre Preocessing time
 * are not "folded" at Pre-Precessing time when they could.
 *
 * Not a bug -- just an optimization that could be done
 * (an RFE...so nevermind...)
 *
 */

#if PreProc_Groks_const_ints_as_const
static const int alt_last_index = (const) num_days - 1;
#endif

int main () {
    printf("last_index = %d", last_index);

#if PreProc_Groks_const_ints_as_const
    printf(", alt_last_index = %d", alt_last_index);
#endif
    
    printf("\n");
} 

/* vim: ts=4:sw=4
 */

The fact that C++ "fixes" this isn't really a difference in the language, it's just a 'next-generation' of the compile time constant folding.  In "C" you'd
have to do the same thing using "#define"'s which just looked uglier...

Can you think of any backward incompatibility if "C were to rold compile
time constants the same way C++ did?

Obviously, that optimization would have to be disabled if one tried
to take the address of one of the values that has been folded as a constant.

If you don't have r/o-segment or text-write segment disabled, you could 
do this in C:
static const int c=1+1;
int * trouble=&c;
++*trouble;
static const int d=c;

The pre-processor would have to do the same type of optimization disabling detection due to  anonymous memory assignments that are sometimes disabled
for similar reasons when detectable at runtime.  Hopefully in C++ that'd
throw an exception...

It'd have to say that anyone who got that 'fancy' at compile time should
be strung up and tickled harshly in front of their peers. :-), but it'd
probably eventually happen by accident...to anyone.

-l

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "gcc" complains about a constant being non constant...
  2009-07-10 21:53     ` Linda A. Walsh
@ 2009-07-11  0:53       ` Ian Lance Taylor
  0 siblings, 0 replies; 8+ messages in thread
From: Ian Lance Taylor @ 2009-07-11  0:53 UTC (permalink / raw)
  To: Linda A. Walsh; +Cc: Andrew Haley, Bill McEnaney, gcc-help

"Linda A. Walsh" <gcc@tlinx.org> writes:

> The fact that C++ "fixes" this isn't really a difference in the language, it's just a 'next-generation' of the compile time constant folding.  In "C" you'd
> have to do the same thing using "#define"'s which just looked uglier...

I think it is clearly a difference in the language, in that the
respective language standards spell out how things should be handled.


> Can you think of any backward incompatibility if "C were to rold compile
> time constants the same way C++ did?

The C language standard was carefully written to not require the
compiler to implement target arithmetic.  This is particularly an issue
for floating point operations, but it also arises for, e.g., signed
magnitude machines, which were a consideration at the time the C
standard was first written.

The C standard specifies that the preprocessor is explicitly permitted
to use host arithmetic, but such permission would not be appropriate for
constants which are not handled by the preprocessor.

Ian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "gcc" complains about a constant being non constant...(sorry for dup)
  2009-07-06  5:38 "gcc" complains about a constant being non constant...(sorry for dup) Linda A. Walsh
  2009-07-06  9:47 ` Andrew Haley
@ 2009-07-08 13:47 ` Kalle Olavi Niemitalo
  1 sibling, 0 replies; 8+ messages in thread
From: Kalle Olavi Niemitalo @ 2009-07-08 13:47 UTC (permalink / raw)
  To: Linda A. Walsh; +Cc: gcc-help

"Linda A. Walsh" <gcc@tlinx.org> writes:

> Compile time output:
> ct.c:10: error: initializer element is not constant
> ct.c:11: error: initializer element is not constant

If you compile the program as C++ rather than C, then these
errors go away, and GCC 4.3.1 propagates the constants to the
printf call:

	movl	$6, 8(%esp)
	movl	$7, 4(%esp)
	movl	$.LC0, (%esp)
	call	printf

This is one difference in the meaning of const between C and C++.
Another difference is that in C++, const variables defined
outside of functions are static by default, although one can
override that with extern.  That doesn't matter in your program
because the variables were static already.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: "gcc" complains about a constant being non constant...(sorry  for dup)
  2009-07-06  5:38 "gcc" complains about a constant being non constant...(sorry for dup) Linda A. Walsh
@ 2009-07-06  9:47 ` Andrew Haley
  2009-07-08 13:47 ` Kalle Olavi Niemitalo
  1 sibling, 0 replies; 8+ messages in thread
From: Andrew Haley @ 2009-07-06  9:47 UTC (permalink / raw)
  To: Linda A. Walsh; +Cc: gcc-help

Linda A. Walsh wrote:
> (Sorry if this is a dup, somehow my from address got mangled with the from
> addr having this message being sent from my system's MAILER DAEMON! 
> Weird.)
> 
> I have a "proglet", included below (twice, in fact! :-), first with line
> numbering for referring to the error messages, and a 2nd time without
> line numbers to allow for easy cut & pasting to try it in your local
> environment.
> 
> The error output appears to indicate a problem with compile-time constant
> folding.
> 
> gcc --version shows:
> gcc (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]
> 
> Compile time output:
> ct.c:10: error: initializer element is not constant
> ct.c:11: error: initializer element is not constant
> 
> Here's the proglet w/line numbering for reference:
> ------
> 1 #include <stdio.h>
> 2 #include <stdlib.h>
> 3 #include <strings.h>
> 4  5 typedef const char * String;
> 6  7 static const String days [] ={"Sun", "Mon", "Tue", "Wed", "Thu" ,
> "Fri", "Sat"};
> 8 static const int sizeof_days            = sizeof(days);
> 9 static const int sizeof_String          = sizeof(String);
> 10 static const int numdays                = sizeof_days / sizeof_String;
> 11 static const int last_index=numdays-1;
> 12 13 int main (){
> 14         printf("numdays=%d, lastidx=%d\n",numdays,last_index);
> 15 }
> --------
> 
> if, in line 8, sizeof(days) is a constant,  AND in line 9,
> sizeof(String) is
> a constant, then how can their division (in line 10) NOT be a constant?

Simple: sizeof(days) is a constant, but sizeof_days is not.  Reason: because
the C language standard says so.  A const variable is not a constant.  It'd be
nice if it were.

Andrew.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* "gcc" complains about a constant being non constant...(sorry for dup)
@ 2009-07-06  5:38 Linda A. Walsh
  2009-07-06  9:47 ` Andrew Haley
  2009-07-08 13:47 ` Kalle Olavi Niemitalo
  0 siblings, 2 replies; 8+ messages in thread
From: Linda A. Walsh @ 2009-07-06  5:38 UTC (permalink / raw)
  To: gcc-help

(Sorry if this is a dup, somehow my from address got mangled with the from
addr having this message being sent from my system's MAILER DAEMON!  Weird.)

I have a "proglet", included below (twice, in fact! :-), first with line numbering for referring to the error messages, and a 2nd time without line numbers to allow for easy cut & pasting to try it in your local environment.

The error output appears to indicate a problem with compile-time constant
folding.

gcc --version shows:
gcc (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]

Compile time output:
ct.c:10: error: initializer element is not constant
ct.c:11: error: initializer element is not constant

Here's the proglet w/line numbering for reference:
------
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <strings.h>
 4  5 typedef const char * String;
 6  7 static const String days [] ={"Sun", "Mon", "Tue", "Wed", "Thu" , "Fri", "Sat"};
 8 static const int sizeof_days            = sizeof(days);
 9 static const int sizeof_String          = sizeof(String);
10 static const int numdays                = sizeof_days / sizeof_String;
11 static const int last_index=numdays-1;
12 13 int main (){
14         printf("numdays=%d, lastidx=%d\n",numdays,last_index);
15 }
--------

if, in line 8, sizeof(days) is a constant,  AND in line 9, sizeof(String) is
a constant, then how can their division (in line 10) NOT be a constant?
Similarly, how would a "constant value" minus one, (as in line 11) also
not be a constant?

This seems too obvious for it not to have been caught before.  Is this a
designed feature deficit, or did I really stumble upon a bug in such
mature code that it wouldn't have been reported and fixed years ago?
:-)


I've also included same program, below, without line numbers (for easy
cut & paste to a test file).

Am I missing something about constant folding, or is it this some unlikely
fluke?


Thanks,
Linda


---------------------
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

typedef const char * String;

static const String days [] ={"Sun", "Mon", "Tue", "Wed", "Thu" , "Fri", "Sat"};
static const int sizeof_days            = sizeof(days);
static const int sizeof_String          = sizeof(String);
static const int numdays                = sizeof_days / sizeof_String;
static const int last_index=numdays-1;

int main (){
       printf("numdays=%d, lastidx=%d\n",numdays,last_index);
}
-----------------------------

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-07-11  0:53 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-06 10:56 "gcc" complains about a constant being non constant...(sorry for dup) Bill McEnaney
2009-07-06 19:13 ` "gcc" complains about a constant being non constant Linda A. Walsh
2009-07-08  9:03   ` Andrew Haley
2009-07-10 21:53     ` Linda A. Walsh
2009-07-11  0:53       ` Ian Lance Taylor
  -- strict thread matches above, loose matches on Subject: below --
2009-07-06  5:38 "gcc" complains about a constant being non constant...(sorry for dup) Linda A. Walsh
2009-07-06  9:47 ` Andrew Haley
2009-07-08 13:47 ` Kalle Olavi Niemitalo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).