* 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-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?
@ 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
* 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-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: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 4:57 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 4:57 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
* 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
* 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 --
[not found] <s8e49edd.056@ymer>
2000-03-31 3:17 ` Volatile constants? Richard Earnshaw
2000-04-03 2:33 Christian Häggström
-- strict thread matches above, loose matches on Subject: below --
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-03-29 4:57 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
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).