Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Amusing C, amusing compiler

Reply
Thread Tools

Amusing C, amusing compiler

 
 
Ark
Guest
Posts: n/a
 
      10-06-2006
A function
int foo(struct T *x)
{
return (x+1)-x;
}
should always return a 1, no matter how T is defined. (And int could be
replaced with ptrdiff_t for you pedants.)

For one thing, it was amusing to watch how my compiler (the famed IAR
EWARM for ARM) jumps through hoops to arrive at this answer.
[ For sizeof(struct T)==6,
00000000 061080E2 ADD R1,R0,#+6
00000004 18209FE5 LDR R2,??foo_0 ;; 0xaaaaaaab
00000008 92318CE0 UMULL R3,R12,R2,R1
0000000C 2CC1A0E1 LSR R12,R12,#+2
00000010 0210A0E1 MOV R1,R2
00000014 912083E0 UMULL R2,R3,R1,R0
00000018 2331A0E1 LSR R3,R3,#+2
0000001C 03004CE0 SUB R0,R12,R3
00000020 0EF0A0E1 MOV PC,LR ;; return
??foo_0:
00000024 ABAAAAAA DC32 0xaaaaaaab
]

How does your compiler fare?
[MSVC gets it right:
mov eax, 1
ret 0
]

Another thing is that, logically, since the actual type doesn't matter,
it could be an incomplete type. However, if I just say
struct T;
before the foo's body, compilation fails. Is it good and/or justified?

- Ark
 
Reply With Quote
 
 
 
 
jacob navia
Guest
Posts: n/a
 
      10-06-2006
Ark wrote:
> A function
> int foo(struct T *x)
> {
> return (x+1)-x;
> }
> should always return a 1, no matter how T is defined. (And int could be
> replaced with ptrdiff_t for you pedants.)
>
> For one thing, it was amusing to watch how my compiler (the famed IAR
> EWARM for ARM) jumps through hoops to arrive at this answer.
> [ For sizeof(struct T)==6,
> 00000000 061080E2 ADD R1,R0,#+6
> 00000004 18209FE5 LDR R2,??foo_0 ;; 0xaaaaaaab
> 00000008 92318CE0 UMULL R3,R12,R2,R1
> 0000000C 2CC1A0E1 LSR R12,R12,#+2
> 00000010 0210A0E1 MOV R1,R2
> 00000014 912083E0 UMULL R2,R3,R1,R0
> 00000018 2331A0E1 LSR R3,R3,#+2
> 0000001C 03004CE0 SUB R0,R12,R3
> 00000020 0EF0A0E1 MOV PC,LR ;; return
> ??foo_0:
> 00000024 ABAAAAAA DC32 0xaaaaaaab
> ]
>
> How does your compiler fare?
> [MSVC gets it right:
> mov eax, 1
> ret 0
> ]
>
> Another thing is that, logically, since the actual type doesn't matter,
> it could be an incomplete type. However, if I just say
> struct T;
> before the foo's body, compilation fails. Is it good and/or justified?
>
> - Ark


It is amusing how stupid machines are.
You know? You forget a semi colon and they get all screwed up.

Stupid isn't it?

1) If x is double. If x is a NAN or INFinity,
the result is not one but NAN.
2) For x == INTMAX, x+1-x depends on how the operations are
ordered by the compiler. If it makes (x-1)+x then is 1,
otherwise it overflows and there is undefined behavior.
If INTMAX+1 wraps around to negative the result is not one
either

3) If x is unsigned and equal to UINT_MAX, the the result is -x.

4) There is an infinite number of this kind of optimizations
x+1-x
x+2-x
x+3-x
x+4-x+2*x-x-x
x+5-x + 3*x-x-x-x + 5765*x-5000*x-765*x

For that last expression that should be 5 Microsoft generates:
mov eax, DWORD PTR _x$[ebp]
add eax, 5
sub eax, DWORD PTR _x$[ebp]
mov ecx, DWORD PTR _x$[ebp]
imul ecx, 3
add eax, ecx
sub eax, DWORD PTR _x$[ebp]
sub eax, DWORD PTR _x$[ebp]
sub eax, DWORD PTR _x$[ebp]
mov edx, DWORD PTR _x$[ebp]
imul edx, 5765
add eax, edx
mov ecx, DWORD PTR _x$[ebp]
imul ecx, 5000
sub eax, ecx
mov edx, DWORD PTR _x$[ebp]
imul edx, 765
sub eax, edx

Stupid isn't it???


What is not so clever is to expect from machines that they
understand anything.

A machine doesn't grasp anything, nor it understands anything.
It is we that give the understanding to the machines, and we
have to do it mostly by enumeration. There is no way for
a machine to make an abstraction, I suspect that is because
THEY DO NOT THINK!!!!

Happy for us programmers, they are not there yet, not will be there
for a long while.

Brains THINK, you see? Machines have no brains and can't generalize
vcan't build from experience, can't do anything. All they have is
a fake of "intelligence" in the form of complex enumerations
of facts and algorithms that humans program into them.

Brains THINK, machines execute. That's why machines never do any
mistake. Only WE can do mistakes. It is because only WE have
intent. They do not have any.

jacob
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      10-06-2006
jacob navia wrote:
> Ark wrote:
>
>> A function
>> int foo(struct T *x)
>> {
>> return (x+1)-x;
>> }
>> should always return a 1, no matter how T is defined. (And int could
>> be replaced with ptrdiff_t for you pedants.)
>>

>
> It is amusing how stupid machines are.
> You know? You forget a semi colon and they get all screwed up.
>
> Stupid isn't it?
>
> 1) If x is double. If x is a NAN or INFinity,
> the result is not one but NAN.


But the example is only doing pointer arithmetic..

--
Ian Collins.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      10-06-2006
Ark wrote:
>
> Another thing is that, logically, since the actual type doesn't matter,
> it could be an incomplete type. However, if I just say
> struct T;
> before the foo's body, compilation fails. Is it good and/or justified?
>

The expression still has to be parsed before it is optimised, so the
size of T has to be know in order to attempt the pointer arithmetic.

--
Ian Collins.
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      10-06-2006
Ark wrote:
>
> A function
> int foo(struct T *x)
> {
> return (x+1)-x;
> }
> should always return a 1, no matter how T is defined.
> (And int could be
> replaced with ptrdiff_t for you pedants.)


> Another thing is that, logically,
> since the actual type doesn't matter,
> it could be an incomplete type. However, if I just say
> struct T;
> before the foo's body, compilation fails. Is it good and/or justified?


It is good and/or justified.

If x is a pointer to an incomplete type, then (x + 1) is undefined.

You can't do pointer arithmetic on pointers to incomplete types.

--
pete
 
Reply With Quote
 
straywithsmile@gmail.com
Guest
Posts: n/a
 
      10-06-2006
In visual studio 2005, if the struct T haven't defined( NOT declared),
the compiler will give an error message, if it has been defined, and
you just give a pointer that is not initialed, e.g
struct T* ptr;
foo(ptr);
the visual studio 2005, also give an run-time error message, said ptr
is not initialed, but on GCC it is right, and will return one; my
compiler DJGPP's assemble tell me that, the foo is optimized by the
compiler, and return 1 directly.

 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      10-07-2006
In article <(E-Mail Removed)>,
pete <(E-Mail Removed)> wrote:

>You can't do pointer arithmetic on pointers to incomplete types.


Especially if it is void*
--
Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      10-07-2006
http://www.velocityreviews.com/forums/(E-Mail Removed)-cnrc.gc.ca (Walter Roberson) writes:
> In article <(E-Mail Removed)>,
> pete <(E-Mail Removed)> wrote:
>
>>You can't do pointer arithmetic on pointers to incomplete types.

>
> Especially if it is void*


Why "especially"?

<OT>gcc allows arithmitec on void* as an extension; it doesn't allow
arithmitec on pointers to other incomplete types.</OT>

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
websnarf@gmail.com
Guest
Posts: n/a
 
      10-07-2006
Ian Collins wrote:
> jacob navia wrote:
> > Ark wrote:
> >> A function
> >> int foo(struct T *x)
> >> {
> >> return (x+1)-x;
> >> }
> >> should always return a 1, no matter how T is defined. (And int could
> >> be replaced with ptrdiff_t for you pedants.)
> >>

> >
> > It is amusing how stupid machines are.
> > You know? You forget a semi colon and they get all screwed up.
> >
> > Stupid isn't it?
> >
> > 1) If x is double. If x is a NAN or INFinity,
> > the result is not one but NAN.

>
> But the example is only doing pointer arithmetic..


Setting a pointer beyond its boundaries apparently leads to undefined
behavior. This suggests that on at least some theoretical platforms it
might be worth while to not do this simplification. If I am not
mistaken, unsigned integers is the only data type where the standard
guarantees the applicability of that simplification.

Another more pressing point -- what is the use of such a nonsensical
simplification? Who is subtracting two pointers where the base pointer
type is clearly the same, rather than doing the simplification by hand?
Maybe some macro shenanigans, but to be honest I have never found
myself doing that and *not* simplifying it by hand. Personally, I
judge the compiler optimizer for its ability to generate good code
where human intevention is either impossible (jump tables) or difficult
(software-based register renaming.) This is why WATCOM C/C++ is still
in my arsenal of compilers.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

 
Reply With Quote
 
Simon Biber
Guest
Posts: n/a
 
      10-07-2006
(E-Mail Removed) wrote:
> In visual studio 2005, if the struct T haven't defined( NOT declared),
> the compiler will give an error message, if it has been defined, and
> you just give a pointer that is not initialed, e.g
> struct T* ptr;
> foo(ptr);
> the visual studio 2005, also give an run-time error message, said ptr
> is not initialed


Absolutely correct. It's undefined behaviour to add one to an
uninitialised pointer, since it does not point at any object.

VS 2005 is being helpful in diagnosing this undefined behaviour for you,
though it is not required to do so.

> but on GCC it is right, and will return one; my


That's not "right" per se, merely one possible manifestation of
undefined behaviour. The way GCC is behaving is correct but it is not
required to behave in that way.

> compiler DJGPP's assemble tell me that, the foo is optimized by the
> compiler, and return 1 directly.


Compilers are allowed to do that, but not required to do so.

--
Simon.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Amusing thread from a web-forum anthonyberet Computer Support 4 02-04-2005 03:40 PM
Amusing 12-24 Picture Gary Morrison Digital Photography 14 10-27-2003 01:37 AM
Something amusing (origin unknown, apologies to the author ;-) ) slumpy Computer Support 2 08-20-2003 11:35 PM
Re: A bit O/T...But....hmmmmm.......very amusing! paul s Computer Support 0 07-10-2003 07:18 PM
Re: A bit O/T...But....hmmmmm.......very amusing! Ionizer Computer Support 0 07-10-2003 07:03 PM



Advertisments