public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Volatile constants?
@ 2000-03-29  4:57 Christian Häggström
  2000-03-29  7:41 ` Erik Mouw
  2000-03-29  7:45 ` Kevin Handy
  0 siblings, 2 replies; 12+ messages in thread
From: Christian Häggström @ 2000-03-29  4:57 UTC (permalink / raw)
  To: gcc

The GCC manual says "An Inline Function is As Fast As a Macro",
but when I compile this, I got error "initializer element is not constant" on
's' initialization.

inline int abs1(int x) {
   return x<0 ? -x : x;
}
#define abs2(x) (x<0 ? -x : x)

int r = abs1(-7);
int s = abs2(-7);

Is there any option I have to pass?
g++ produces a constructor function for 's' but not for 'r'. Why?

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

* Re: Volatile constants?
  2000-03-29  4:57 Volatile constants? Christian Häggström
@ 2000-03-29  7:41 ` Erik Mouw
  2000-03-29  9:53   ` Alasdair Baird
  2000-03-29  7:45 ` Kevin Handy
  1 sibling, 1 reply; 12+ messages in thread
From: Erik Mouw @ 2000-03-29  7:41 UTC (permalink / raw)
  To: 97nv46; +Cc: gcc

On Wed, 29 Mar 2000 14:56:14 +0200, Q2hyaXN0aWFuIEjkZ2dzdHL2bQ== wrote:
> The GCC manual says "An Inline Function is As Fast As a Macro",
> but when I compile this, I got error "initializer element is not constant" on
> 's' initialization.
> 
> inline int abs1(int x) {
>    return x<0 ? -x : x;
> }
> #define abs2(x) (x<0 ? -x : x)

<nitpick>
You should define this as:

  #define abs2(x) ((x) < 0 ? (-x) : (x))

Rationale: see what happens with your version if you use abs2(2 - 3). The
extra parentesis enforce the correct operator precedence.
</nitpick>

> int r = abs1(-7);
> int s = abs2(-7);
> 
> Is there any option I have to pass?

I don't get that error message. Here is what my compiler says:

  erik@lumiere:/tmp >g++ -v
  Reading specs from /usr/it/packages/gcc/gcc-2.95.2/install/irix65/lib/gcc-lib/mips-sgi-irix6.5/2.95.2/specs
  gcc version 2.95.2 19991024 (release)
  erik@lumiere:/tmp >g++ -Wall -O2 -c foo.c -o foo.o
  erik@lumiere:/tmp >

I think you should upgrade to gcc-2.95.2.


Erik

-- 
J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department
of Electrical Engineering, Faculty of Information Technology and Systems,
Delft University of Technology, PO BOX 5031,  2600 GA Delft, The Netherlands
Phone: +31-15-2785859  Fax: +31-15-2781843  Email J.A.K.Mouw@its.tudelft.nl
WWW: http://www-ict.its.tudelft.nl/~erik/



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

* Re: Volatile constants?
  2000-03-29  4:57 Volatile constants? Christian Häggström
  2000-03-29  7:41 ` Erik Mouw
@ 2000-03-29  7:45 ` Kevin Handy
  2000-03-29 12:18   ` Andi Kleen
  1 sibling, 1 reply; 12+ messages in thread
From: Kevin Handy @ 2000-03-29  7:45 UTC (permalink / raw)
  To: Christian Häggström; +Cc: gcc

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 706 bytes --]

Christian Häggström wrote:
> 
> The GCC manual says "An Inline Function is As Fast As a Macro",
> but when I compile this, I got error "initializer element is not constant" on
> 's' initialization.
> 
> inline int abs1(int x) {
>    return x<0 ? -x : x;
> }
> #define abs2(x) (x<0 ? -x : x)
> 
> int r = abs1(-7);
> int s = abs2(-7);

After preprocess

	int s = (-7<0 ? --7 : -7)

I'd guess that the decrement '--7' is what is causing you the problem
This is why you should always use extra parentheses in your #defines

	#define abs(2) ((x)<0 ? -(x) : (x))

Isn't this in a FAQ somewhere?

> 
> Is there any option I have to pass?
> g++ produces a constructor function for 's' but not for 'r'. Why?

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

* Re: Volatile constants?
  2000-03-29  7:41 ` Erik Mouw
@ 2000-03-29  9:53   ` Alasdair Baird
  2000-03-29 10:05     ` Erik Mouw
  0 siblings, 1 reply; 12+ messages in thread
From: Alasdair Baird @ 2000-03-29  9:53 UTC (permalink / raw)
  To: Erik Mouw; +Cc: 97nv46, gcc

 > > #define abs2(x) (x<0 ? -x : x)
 > 
 > <nitpick>
 > You should define this as:
 > 
 >   #define abs2(x) ((x) < 0 ? (-x) : (x))
 > 
 > Rationale: see what happens with your version if you use abs2(2 - 3). The
 > extra parentesis enforce the correct operator precedence.

I think that you might find the following to actually be correct though:

   #define abs2(x) ((x) < 0 ? -(x) : (x))

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

* Re: Volatile constants?
  2000-03-29  9:53   ` Alasdair Baird
@ 2000-03-29 10:05     ` Erik Mouw
  0 siblings, 0 replies; 12+ messages in thread
From: Erik Mouw @ 2000-03-29 10:05 UTC (permalink / raw)
  To: alasdair; +Cc: 97nv46, gcc

On Wed, 29 Mar 2000 18:49:04 +0100 (BST), Alasdair Baird wrote:
>  > > #define abs2(x) (x<0 ? -x : x)
>  > 
>  > <nitpick>
>  > You should define this as:
>  > 
>  >   #define abs2(x) ((x) < 0 ? (-x) : (x))
>  > 
>  > Rationale: see what happens with your version if you use abs2(2 - 3). The
>  > extra parentesis enforce the correct operator precedence.
> 
> I think that you might find the following to actually be correct though:
> 
>    #define abs2(x) ((x) < 0 ? -(x) : (x))

Yes, you're absolutely right.


Erik

-- 
In theory, practice and theory are the same, but in practice they 
are different -- Larry McVoy



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

* Re: Volatile constants?
  2000-03-29  7:45 ` Kevin Handy
@ 2000-03-29 12:18   ` Andi Kleen
  0 siblings, 0 replies; 12+ messages in thread
From: Andi Kleen @ 2000-03-29 12:18 UTC (permalink / raw)
  To: gcc; +Cc: kth, 97nv46

Kevin Handy <kth@srv.net> writes:
> 
> After preprocess
> 
> 	int s = (-7<0 ? --7 : -7)
> 
> I'd guess that the decrement '--7' is what is causing you the problem
> This is why you should always use extra parentheses in your #defines

This is not true. ANSI-C generates tokens before preprocessing.
The tokens are not concatenated afterwards, unless you use ## 
It should be parsed as - - 7, which is legal C. Maybe some prehistoric
K&R preprocessors do it differently. 
The problem is just that inline calls are not allowed in constant
expressions, and a global definition expects a constant expression
as initializer. inline does not change the grammar here.

-Andi 

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

* Re: Volatile constants?
@ 2000-04-03  2:33 Christian Häggström
  0 siblings, 0 replies; 12+ messages in thread
From: Christian Häggström @ 2000-04-03  2:33 UTC (permalink / raw)
  To: gcc; +Cc: rearnsha, J.A.K.Mouw

> Because even in C++ you have still specified it as a constructor function, 
> not a constant expression.

Is there any way to optimize away constant constructors?
Otherwise, an new option to manage this have been nice.
---
I have another example of GCC's silly constant handling
assume we have an array like this
    int regs[8];
and we want to access 'regs[3]' as 'ebx'

( best viewed with fixed size font )

method 1 const pointer   | method 2 const reference
----------------------   | ------------------------
                // definitions //
typedef int * intp;      | typedef int & intref;
const intp ebx = regs+3; | const intref ebx = regs[3];
              // access example //
void set_ebx(int val) {  | void set_ebx(int val) {
    *ebx = val;          |     ebx = val;
}                        | }
        // asm output (i386,regparm) //
set_ebx:                 | set_ebx:
    movl %eax,regs+12    |     movl %eax,%edx
                         |     movl ebx,%eax
                         |     movl %edx,(%eax)
    ret                  |     ret
                         | .section .rodata
                         | ebx:
                         | .long regs+12

I want to use method 2 because it is cleaner, but do I get different output?

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

* Re: Volatile constants?
       [not found] <s8e49edd.056@ymer>
@ 2000-03-31  3:17 ` Richard Earnshaw
  0 siblings, 0 replies; 12+ messages in thread
From: Richard Earnshaw @ 2000-03-31  3:17 UTC (permalink / raw)
  To: Christian Häggström
  Cc: rearnsha

> inline int abs1(int x) {
>     return x<0 ? -x : x;
> }
> #define abs2(x) ((x)<0 ? -(x) : x)
>  
> int r = abs1(-7);
> int s = abs2(-7);
> 
> >An inline function is NOT a macro, it's still a function.  You can't use a 
> >function as an initializer for a static extent variable in C.
> 
> OK, this is not valid in ANSI C
> In C++, however, this is valid.
> Now, take a look at the assembly output (x86,regparm)
> 
[...]

> Why is 'r' not handled as 's'?
> This is slower and occupies more memory.
> 

Because even in C++ you have still specified it as a constructor function, 
not a constant expression.  All this means is that the your inline 
function will get inlined into your constructors rather than left as a 
stand-alone function that is called by them (try taking the "inline" out 
and see how it changes your assembly output).

R.

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

* Re: Volatile constants?
@ 2000-03-31  2:50 Christian Häggström
  0 siblings, 0 replies; 12+ messages in thread
From: Christian Häggström @ 2000-03-31  2:50 UTC (permalink / raw)
  To: rearnsha; +Cc: gcc, J.A.K.Mouw

inline int abs1(int x) {
    return x<0 ? -x : x;
}
#define abs2(x) ((x)<0 ? -(x) : x)
 
int r = abs1(-7);
int s = abs2(-7);

>An inline function is NOT a macro, it's still a function.  You can't use a 
>function as an initializer for a static extent variable in C.

OK, this is not valid in ANSI C
In C++, however, this is valid.
Now, take a look at the assembly output (x86,regparm)

.data
s:	.long 7
.bss
r:	.zero	4
.text
__static_initialization_and_destruction_0:
	cmpl $65535,%edx
	jne .L86
	testl %eax,%eax
	je .L86
	movl $7,r
.L86:	ret
_GLOBAL_.I.s:
	movl $65535,%edx
	movl $1,%eax
	call __static_initialization_and_destruction_0
	ret
.section	.ctors,"aw"
	.long	 _GLOBAL_.I.s

Why is 'r' not handled as 's'?
This is slower and occupies more memory.

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

* Re: Volatile constants?
  2000-03-29 23:31 Christian Häggström
@ 2000-03-30  4:21 ` Richard Earnshaw
  0 siblings, 0 replies; 12+ messages in thread
From: Richard Earnshaw @ 2000-03-30  4:21 UTC (permalink / raw)
  To: Christian Häggström
  Cc: rearnsha

> /* Okay I forgot the parenthesis, but that was not my point */
> 
> The GCC manual says "An Inline Function is As Fast As a Macro",
> but when I compile this (as C code), I got error "initializer element is not constant" on
> 's' initialization.
> 
> inline int abs1(int x) {
>     return x<0 ? -x : x;
> }
> #define abs2(x) ((x)<0 ? -(x) : (x))
> 
> int r = abs1(-7);
> int s = abs2(-7);
> 
> Is there any option I have to pass?
> 
> >I don't get that error message. Here is what my compiler says: ...
> 
> Okay you use g++. I use the c compiler.
> g++ don t generate an error (not even a warning) for this,
> but makes an constructor function, 'static_initialization_and_destruction'-something
> That is not what I want and it is NOT as fast as a macro.
> 
> >I think you should upgrade to gcc-2.95.2.
> I compiled with that version, yes
> 
> I ll be glad for any help
> 


An inline function is NOT a macro, it's still a function.  You can't use a 
function as an initializer for a static extent variable in C.

Speed has nothing to do with it; the semantics are different.

Now if the manual said "an inline function is the SAME as a macro", then 
you would have a legitimate complaint.  But it doesn't, so you don't.

R.


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

* Re: Volatile constants?
@ 2000-03-29 23:31 Christian Häggström
  2000-03-30  4:21 ` Richard Earnshaw
  0 siblings, 1 reply; 12+ messages in thread
From: Christian Häggström @ 2000-03-29 23:31 UTC (permalink / raw)
  To: J.A.K.Mouw; +Cc: gcc

/* Okay I forgot the parenthesis, but that was not my point */

The GCC manual says "An Inline Function is As Fast As a Macro",
but when I compile this (as C code), I got error "initializer element is not constant" on
's' initialization.

inline int abs1(int x) {
    return x<0 ? -x : x;
}
#define abs2(x) ((x)<0 ? -(x) : (x))

int r = abs1(-7);
int s = abs2(-7);

Is there any option I have to pass?

>I don't get that error message. Here is what my compiler says: ...

Okay you use g++. I use the c compiler.
g++ don t generate an error (not even a warning) for this,
but makes an constructor function, 'static_initialization_and_destruction'-something
That is not what I want and it is NOT as fast as a macro.

>I think you should upgrade to gcc-2.95.2.
I compiled with that version, yes

I ll be glad for any help

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

* Volatile constants?
@ 2000-02-22  0:52 Christian Häggström
  0 siblings, 0 replies; 12+ messages in thread
From: Christian Häggström @ 2000-02-22  0:52 UTC (permalink / raw)
  To: gcc

compiling this code

   extern void f() asm("f");
   void f() {}
   int end = (int)f + 256;

gives as expected this assembly output (shortened)

.text
f:
	ret
.data
end:
	.long f+256

That looks fine, but I wish to right shift the adress to f()

   int seg = (int)f >> 16;

This gives the far more ugly code (some labels removed)

.bss
seg:
	.zero	4
.text
__static_initialization_and_destruction_0:
	cmpl $65535,12(%ebp)
	jne .L8
	cmpl $0,8(%ebp)
	je .L8
	movl $f__Fv,%eax
	sarl $16,%eax
	movl %eax,seg
	ret
_GLOBAL_.I.f:
	subl $8,%esp
	addl $-8,%esp
	pushl $65535
	pushl $1
	call __static_initialization_and_destruction_0
	ret
.section	.ctors,"aw"
	.long	 _GLOBAL_.I.f

	.ident	"GCC: (GNU) 2.95.2 19991024 (release)"

Why? Can ld only handle + and -, and not << >> * / and other operators?

Anyway, I have found and use a way to work around this:
1. Substitute the expression with a symbol
2. Calculate the exression in a ld script

The above example becomes:

   extern int f_rsh_16;
   int seg = (int)&f_rsh_16;

and then I run the linker script

   SECTIONS {
      f_rsh_16 = f >> 16;
   }

This way is very ugly, does anybody know a better way?

$ ld -v
GNU ld version 2.9.5 (with BFD 2.9.5.0.16)

I reconfigured gcc with --with-gnu-ld, but it was the same thing.

Maybe this is a linker limitation... Does GNU ld have a mailing list?

Best regards, <mrz@hehe.com>

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

end of thread, other threads:[~2000-04-03  2:33 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-29  4:57 Volatile constants? Christian Häggström
2000-03-29  7:41 ` Erik Mouw
2000-03-29  9:53   ` Alasdair Baird
2000-03-29 10:05     ` Erik Mouw
2000-03-29  7:45 ` Kevin Handy
2000-03-29 12:18   ` Andi Kleen
  -- strict thread matches above, loose matches on Subject: below --
2000-04-03  2:33 Christian Häggström
     [not found] <s8e49edd.056@ymer>
2000-03-31  3:17 ` Richard Earnshaw
2000-03-31  2:50 Christian Häggström
2000-03-29 23:31 Christian Häggström
2000-03-30  4:21 ` Richard Earnshaw
2000-02-22  0:52 Christian Häggström

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).