473,320 Members | 1,831 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Casting function pointers

Hello everyone,

Does the following code invoke undefined behavior?

In other words, is it dangerous to lie to the compiler about a
function's return type, when the return type is the same size or
smaller than sizeof(int).

It seems to me there could be platforms where
char = 8 bits, short = 16 bits, int = 32 bits,
and, on that hypothetical platform, chars, shorts, and ints
might be stored in different registers altogether?
int printf(const char *format, ...);

typedef int fp_t(void);

int f1(void)
{
register int res = -1;
return res;
}

short f2(void)
{
register short res = -2;
return res;
}

signed char f3(void)
{
register signed char res = -3;
return res;
}

void foo(fp_t fp)
{
printf("%d\n", fp());
}

int main(void)
{
foo(f1);
foo((fp_t *)f2);
foo((fp_t *)f3);
return 0;
}

--
Regards, Nudge
Nov 15 '05 #1
7 1340
In article <43***********************@news.free.fr>,
Nudge <ho******@kma.eu.org> wrote:
In other words, is it dangerous to lie to the compiler about a
function's return type, when the return type is the same size or
smaller than sizeof(int). It seems to me there could be platforms where
char = 8 bits, short = 16 bits, int = 32 bits,
and, on that hypothetical platform, chars, shorts, and ints
might be stored in different registers altogether?


Correct. You cannot presume anything about how values of different
sizes are returned, or even about values of the same size (e.g.,
float vs int) that are not specifically defined as being
compatible.

If I recall correctly, the standard does define some compatibilities,
mostly having to do with type qualifiers such as "const".
--
Is there any thing whereof it may be said, See, this is new? It hath
been already of old time, which was before us. -- Ecclesiastes
Nov 15 '05 #2
Nudge <ho******@kma.eu.org> writes:
Does the following code invoke undefined behavior?
Yes.
In other words, is it dangerous to lie to the compiler about a
function's return type, when the return type is the same size or
smaller than sizeof(int).
Yes.
It seems to me there could be platforms where
char = 8 bits, short = 16 bits, int = 32 bits,
and, on that hypothetical platform, chars, shorts, and ints
might be stored in different registers altogether?


Yes. A related situation occurs on x86, where functions might
return `char' values in the AL 8-bit register. If the caller
expects to receive 32 bits it will read EAX, a 32-bit register
that contains AL as its least significant 8 bits. The most
significant 24 bits of the return value can then be any arbitrary
value.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 15 '05 #3
"Nudge" <ho******@kma.eu.org> wrote in message
news:43***********************@news.free.fr...
Hello everyone,

Does the following code invoke undefined behavior?

In other words, is it dangerous to lie to the compiler about a
function's return type, when the return type is the same size or
smaller than sizeof(int).

It seems to me there could be platforms where
char = 8 bits, short = 16 bits, int = 32 bits,
and, on that hypothetical platform, chars, shorts, and ints
might be stored in different registers altogether?


"It seems to me there could be platforms where char = 8 bits, short = 16
bits, int = 32 bits, and, on that hypothetical platform, chars, shorts,
and ints might be stored in different registers"
Nov 15 '05 #4
Ben Pfaff wrote:
Nudge <ho******@kma.eu.org> writes:

Does the following code invoke undefined behavior?

Yes.

In other words, is it dangerous to lie to the compiler about a
function's return type, when the return type is the same size or
smaller than sizeof(int).

Yes.

It seems to me there could be platforms where
char = 8 bits, short = 16 bits, int = 32 bits,
and, on that hypothetical platform, chars, shorts, and ints
might be stored in different registers altogether?

Yes. A related situation occurs on x86, where functions might
return `char' values in the AL 8-bit register. If the caller
expects to receive 32 bits it will read EAX, a 32-bit register
that contains AL as its least significant 8 bits. The most
significant 24 bits of the return value can then be any arbitrary
value.
int main(void){char

p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\ \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\ );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof > p-1;putchar(p[i]\ );}return 0;}


One of these days I'll compile your signature and figure out what in the
world it does. I've seen it enough that it's starting to bother me now ;)

Nov 15 '05 #5
Joe Estock <je*****@NOSPAMnutextonline.com> writes:
One of these days I'll compile your signature and figure out what in the
world it does. I've seen it enough that it's starting to bother me now ;)


For what it's worth, I actually have two different compilable
signatures.
--
"When in doubt, treat ``feature'' as a pejorative.
(Think of a hundred-bladed Swiss army knife.)"
--Kernighan and Plauger, _Software Tools_
Nov 15 '05 #6
Ben Pfaff wrote:
Nudge wrote:

Does the following code invoke undefined behavior?

Yes.

In other words, is it dangerous to lie to the compiler about a
function's return type, when the return type is the same size or
smaller than sizeof(int).

Yes.

It seems to me there could be platforms where
char = 8 bits, short = 16 bits, int = 32 bits,
and, on that hypothetical platform, chars, shorts, and ints
might be stored in different registers altogether?

Yes. A related situation occurs on x86, where functions might
return `char' values in the AL 8-bit register. If the caller
expects to receive 32 bits it will read EAX, a 32-bit register
that contains AL as its least significant 8 bits. The most
significant 24 bits of the return value can then be any arbitrary
value.


As a matter of fact, I was thrown off by GCC's behavior on Linux/x86:

f1:
movl $-1, %eax
ret
f2:
movl $-2, %eax
cwtl
ret
f3:
movb $-3, %al
movsbl %al,%eax
ret

I thought there might be a good reason for GCC to insist on widening the
result to 32 bits in f2 and f3. (I imagined some kind of integral
promotion rule might come into play?)

Nudge
Nov 17 '05 #7
Grumble <de*****@kma.eu.org> writes:
Ben Pfaff wrote:
Yes. A related situation occurs on x86, where functions might
return `char' values in the AL 8-bit register. If the caller
expects to receive 32 bits it will read EAX, a 32-bit register
that contains AL as its least significant 8 bits. The most
significant 24 bits of the return value can then be any arbitrary
value.
As a matter of fact, I was thrown off by GCC's behavior on Linux/x86:


[...where f3() returns signed char...]
f3:
movb $-3, %al
movsbl %al,%eax
ret

I thought there might be a good reason for GCC to insist on widening the
result to 32 bits in f2 and f3. (I imagined some kind of integral
promotion rule might come into play?)


The System V ABI for i386 actually says that scalar return values
go in EAX. It doesn't say anything about using only AX or AL for
`short' or `char'. I imagine that it's because of this very
issue. (That's why I said "might": other ABIs for i386 could be
different, but I'm only familiar with the System V ABI.)
--
Just another C hacker.
Nov 17 '05 #8

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

Similar topics

4
by: Jacob Jensen | last post by:
This question has probably been asked a million time, but here it comes again. I want to learn the difference between the three type cast operators: static_cast, reinterpret_cast, dynamic_cast. A...
10
by: Dirk Vanhaute | last post by:
I have only small knowledge of c++, but I would like to compile the example in http://support.microsoft.com/kb/q246772/ HOWTO: Retrieve and Set the Default Printer in Windows I included "#include...
16
by: He Shiming | last post by:
Hi, I'm having a little bit of trouble regarding pointer casting in my program. I don't understand why the following two cases produce different results. Case 1: IInterface *pInterface = new...
35
by: ytrama | last post by:
Hi, I have read in one of old posting that don't cast of pointer which is returned by the malloc. I would like to know the reason. Thanks in advance, YTR
5
by: JS | last post by:
I give a function a void pointer as an argument. But in the function I would like to treat this argument as an integer (only pointers to integers will be sent to the function) therefor I would like...
28
by: Peter Olcott | last post by:
I want to make a generic interface between a scripting language and native code, the native code and the interpreter will both be written in C++. The interpreter will probably be implemented as a...
17
by: sophia.agnes | last post by:
Hi , I was going through peter van der linden's book Expert C programming, in this book there is a section named "How and why to cast" the author then says as follows (float) 3 - it's a...
9
by: Taras_96 | last post by:
Hi everyone, I was experimenting with static_cast and reinterpret cast #include <iostream> struct A1 { int a; }; struct A2 { double d; }; struct B : public A1, A2
5
by: jason.cipriani | last post by:
There have been some recent threads about casting pointers to and from void* that have me rethinking some of my usual practices. I have a couple of questions. 1. What is the purpose of C++'s...
101
by: Tinkertim | last post by:
Hi, I have often wondered if casting the return value of malloc() (or friends) actually helps anything, recent threads here suggest that it does not .. so I hope to find out. For instance : ...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.