473,761 Members | 1,764 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Amusing C, amusing compiler

Ark
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
Oct 6 '06 #1
29 2375
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 "intelligen ce" 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
Oct 6 '06 #2
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.
Oct 6 '06 #3
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.
Oct 6 '06 #4
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
Oct 6 '06 #5
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.

Oct 6 '06 #6
In article <45***********@ mindspring.com> ,
pete <pf*****@mindsp ring.comwrote:
>You can't do pointer arithmetic on pointers to incomplete types.
Especially if it is void*
--
Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
Oct 7 '06 #7
ro******@ibd.nr c-cnrc.gc.ca (Walter Roberson) writes:
In article <45***********@ mindspring.com> ,
pete <pf*****@mindsp ring.comwrote:
>>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_Keit h) ks***@mib.org <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.
Oct 7 '06 #8
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/

Oct 7 '06 #9
Ark
we******@gmail. com wrote:
<snip>
Setting a pointer beyond its boundaries apparently leads to undefined
behavior.
No. I can address (but not dereference) one beyond
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.
Oh. It's a boiled down example from real life. The origin is indeed from
a macro.
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.)
Also consider how they optimize constant expressions and eliminate
common subexpressions. The latter may not be yours but of the compiler's
own production. Add instruction scheduling, data rearrangement. function
inlining, function prologue/epilogue optimization etc.
- Ark
Oct 7 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
2332
by: Jeff Epler | last post by:
Hello. Recently, Generator Comprehensions were mentioned again on python-list. I have written an implementation for the compiler module. To try it out, however, you must be able to rebuild Python from source, because it also requires a change to Grammar. 1. Edit Python-2.3/Grammar/Grammar and add an alternative to the "listmaker" production: -listmaker: test ( list_for | (',' test)* )
12
1780
by: Bob Nelson | last post by:
The November 2003 edition of the ``C/C++ Users Journal'' contains a multi-paged advertising section for Microsoft's Visual C++. NET 2003 product. One section focuses on the compiler as being one of the most ISO compliant on any platform. Overall, the ad is rather interesting and has some worthwhile code snippets. - The amusing part is the declaration of ``main'' in an example showing support for function template specialization:
0
1137
by: Active8 | last post by:
This is amusing. I've got 2 windowing functions for Hamming and Hanning windows I was rewriting and I got ham and han as variables mixed up. vector<MCComplex> vOut = vIn; double han = 0.5 - 0.5 * cos( factor * i ); vOut.SetReal( ham * vOut.GetReal() );
5
1538
by: Colin King | last post by:
The following code also shows some amusing C grammar features: /* typedef unsigned int uint_t ... */ int typedef unsigned uint_t; /* defaults to int type in typedef... */ typedef int_t; main() {
0
2401
by: rollasoc | last post by:
Hi, I seem to be getting a compiler error Internal Compiler Error (0xc0000005 at address 535DB439): likely culprit is 'BIND'. An internal error has occurred in the compiler. To work around this problem, try simplifying or changing the program near the locations listed below. Locations at the top of the list are closer to the point at which the
3
5266
by: Mark Rockman | last post by:
------ Build started: Project: USDAver2, Configuration: Debug .NET ------ Preparing resources... Updating references... Performing main compilation... error CS0583: Internal Compiler Error (0xc0000005 at address 535F072A): likely culprit is 'BIND'. An internal error has occurred in the compiler. To work around this problem, try simplifying or changing the program near the locations listed below. Locations at the top of the list are...
41
18216
by: Miroslaw Makowiecki | last post by:
Where can I download Comeau compiler as a trial version? Thanks in advice.
0
9554
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9377
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10136
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9989
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
7358
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6640
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5405
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3913
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2788
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.