473,568 Members | 2,850 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Undefined behavior - 2 queries

Hi -

Great group!

I have 2 queries about undefined behavior:

1) Is the following code undefined?

float myfunction(floa t f)
{
if(sizeof(float ) & sizeof(int)) {
/* use slow ordinary FP operations */
} else {
int i = *(int *)&f;
/* do clever bit-twiddling floating-point operation */
}
}

It only attempts to access the float as an integer when this makes
sense.

2) I've seen code like the following:

struct s {
int a;
char *b;
float c;
} s;
int *i = (int *) s;

Isn't this undefined? Won't this blow up if the compiler inserts padding
before the first element of the struct?

Cheers!

Sep 8 '07 #1
20 1358
Tommy Vercetti wrote:
Hi -

Great group!

I have 2 queries about undefined behavior:

1) Is the following code undefined?

float myfunction(floa t f)
{
if(sizeof(float ) & sizeof(int)) {
I've tried figuring out why you would use the & operator here. I'm not
seeing it. Did you mean to use != ?
/* use slow ordinary FP operations */
} else {
int i = *(int *)&f;
/* do clever bit-twiddling floating-point operation */
}
}

It only attempts to access the float as an integer when this makes
sense.
The behaviour is outside the scope of the C standard, and very likely also
not defined as an extension by your particular implementation. If you want
your code to be portable, don't do it. If you don't need your code to be
portable, try to figure out how to do it using the extensions your compiler
provides. It's possible you actually do have a compiler that officially
allows your current code as an extension, but I doubt it.
2) I've seen code like the following:

struct s {
int a;
char *b;
float c;
} s;
int *i = (int *) s;

Isn't this undefined?
This is not allowed. You can't convert a structure to a pointer. If you
meant (int *) &s, then it's valid, though I personally prefer to write
&s.a.
Won't this blow up if the compiler inserts padding
before the first element of the struct?
Right. Which is not a problem, since the compiler is not allowed to insert
padding before the first element of the struct.
Sep 8 '07 #2

"Tommy Vercetti" <no@spam.comwro te in message
news:sl******** ************@no spam.invalid...
Hi -

Great group!

I have 2 queries about undefined behavior:

1) Is the following code undefined?

float myfunction(floa t f)
{
if(sizeof(float ) & sizeof(int)) {
/* use slow ordinary FP operations */
} else {
int i = *(int *)&f;
/* do clever bit-twiddling floating-point operation */
}
}

It only attempts to access the float as an integer when this makes
sense.

2) I've seen code like the following:

struct s {
int a;
char *b;
float c;
} s;
int *i = (int *) s;

Isn't this undefined? Won't this blow up if the compiler inserts padding
before the first element of the struct?
The first example should read if(sizeof(float ) != sizeof(int)). If this is
false, the code is almost correct. However the float could contain a legal
float which is a trap value for an integer. You'd have to be on a pretty
pathological platform for this to be a problem, but a conforming
implementation could crash you out.

The second example is OK. The first element of a struct has the same address
as the whole. No prepadding is allowed, though padding may be inserted at
the end or between elements.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Sep 9 '07 #3
On 8 Sep 2007 at 22:45, Harald van Dijk wrote:
Tommy Vercetti wrote:
>Hi -

Great group!

I have 2 queries about undefined behavior:

1) Is the following code undefined?

float myfunction(floa t f)
{
if(sizeof(float ) & sizeof(int)) {

I've tried figuring out why you would use the & operator here. I'm not
seeing it. Did you mean to use != ?
It's an optimization - at the machine code level, most processors will
have a single instruction for &.
> /* use slow ordinary FP operations */
} else {
int i = *(int *)&f;
/* do clever bit-twiddling floating-point operation */
}
}

It only attempts to access the float as an integer when this makes
sense.

The behaviour is outside the scope of the C standard, and very likely also
not defined as an extension by your particular implementation. If you want
your code to be portable, don't do it. If you don't need your code to be
portable, try to figure out how to do it using the extensions your compiler
provides. It's possible you actually do have a compiler that officially
allows your current code as an extension, but I doubt it.
Even though the undefined-behavior lines aren't called in situations
where they'd be undefined? E.g. in the following code:

if(1==2) {
char *p=NULL;
*p; /* KABOOM! */
}

can you really call this UB when the line invoking UB is guaranteed
never to be called?
>
>2) I've seen code like the following:

struct s {
int a;
char *b;
float c;
} s;
int *i = (int *) s;

Isn't this undefined?

This is not allowed. You can't convert a structure to a pointer. If you
meant (int *) &s, then it's valid, though I personally prefer to write
&s.a.
Yes, that was a typo.
>Won't this blow up if the compiler inserts padding
before the first element of the struct?

Right. Which is not a problem, since the compiler is not allowed to insert
padding before the first element of the struct.
I think if you check, the compiler is allowed to insert padding into
structs as it sees fit. In particular, if the address of s isn't
properly aligned for an int then it will have to insert padding!

Sep 9 '07 #4
"Malcolm McLean" <re*******@btin ternet.comwrite s:
"Tommy Vercetti" <no@spam.comwro te in message
news:sl******** ************@no spam.invalid...
[...]
>1) Is the following code undefined?

float myfunction(floa t f)
{
if(sizeof(float ) & sizeof(int)) {
/* use slow ordinary FP operations */
} else {
int i = *(int *)&f;
/* do clever bit-twiddling floating-point operation */
}
}

It only attempts to access the float as an integer when this makes
sense.
[...]
>
The first example should read if(sizeof(float ) != sizeof(int)). If
this is false, the code is almost correct. However the float could
contain a legal float which is a trap value for an integer. You'd have
to be on a pretty pathological platform for this to be a problem, but
a conforming implementation could crash you out.
[...]

It could also fail if int and float have different alignment
requirements.

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 9 '07 #5
"Tommy Vercetti" <no@spam.comwro te in message
news:sl******** ************@no spam.invalid...
On 8 Sep 2007 at 22:45, Harald van Dijk wrote:
>Tommy Vercetti wrote:
>>Hi -

Great group!

I have 2 queries about undefined behavior:

1) Is the following code undefined?

float myfunction(floa t f)
{
if(sizeof(float ) & sizeof(int)) {

I've tried figuring out why you would use the & operator here. I'm not
seeing it. Did you mean to use != ?

It's an optimization - at the machine code level, most processors will
have a single instruction for &.
>> /* use slow ordinary FP operations */
} else {
int i = *(int *)&f;
/* do clever bit-twiddling floating-point operation */
}
}

It only attempts to access the float as an integer when this makes
sense.

The behaviour is outside the scope of the C standard, and very likely
also
not defined as an extension by your particular implementation. If you
want
your code to be portable, don't do it. If you don't need your code to be
portable, try to figure out how to do it using the extensions your
compiler
provides. It's possible you actually do have a compiler that officially
allows your current code as an extension, but I doubt it.

Even though the undefined-behavior lines aren't called in situations
where they'd be undefined? E.g. in the following code:

if(1==2) {
char *p=NULL;
*p; /* KABOOM! */
}

can you really call this UB when the line invoking UB is guaranteed
never to be called?
>>
>>2) I've seen code like the following:

struct s {
int a;
char *b;
float c;
} s;
int *i = (int *) s;

Isn't this undefined?

This is not allowed. You can't convert a structure to a pointer. If you
meant (int *) &s, then it's valid, though I personally prefer to write
&s.a.

Yes, that was a typo.
>>Won't this blow up if the compiler inserts padding
before the first element of the struct?

Right. Which is not a problem, since the compiler is not allowed to
insert
padding before the first element of the struct.

I think if you check, the compiler is allowed to insert padding into
structs as it sees fit. In particular, if the address of s isn't
properly aligned for an int then it will have to insert padding!
No it's not.
If you think about it, inserting a padding byte before the first member
won't solve the problem of alignment.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Sep 9 '07 #6
On Sun, 09 Sep 2007 10:10:00 +0200, Tommy Vercetti wrote:
On 8 Sep 2007 at 22:45, Harald van Dijk wrote:
>Tommy Vercetti wrote:
[snip]
>>float myfunction(floa t f)
{
if(sizeof(float ) & sizeof(int)) {

I've tried figuring out why you would use the & operator here. I'm not
seeing it. Did you mean to use != ?

It's an optimization - at the machine code level, most processors will
have a single instruction for &.
& is bitwise and, it will be nonzero unless the operands have no
set bits in common. Probably you mean ^ (bitwise xor), which is
zero if and only if the operands are equal.
>
>> /* use slow ordinary FP operations */
} else {
int i = *(int *)&f;
/* do clever bit-twiddling floating-point operation */
}
}

It only attempts to access the float as an integer when this makes
sense.

The behaviour is outside the scope of the C standard, and very likely also
not defined as an extension by your particular implementation. If you want
your code to be portable, don't do it. If you don't need your code to be
portable, try to figure out how to do it using the extensions your compiler
provides. It's possible you actually do have a compiler that officially
allows your current code as an extension, but I doubt it.

Even though the undefined-behavior lines aren't called in situations
where they'd be undefined? E.g. in the following code:

if(1==2) {
char *p=NULL;
*p; /* KABOOM! */
}

can you really call this UB when the line invoking UB is guaranteed
never to be called?
The situation is different. The fact that int and float have the
same size doesn't require that they have the same alignment. For
example, imagine that on a particular machine both floats and ints
have 4 bytes, but floats can be placed anywhere, whereas ints must
be aligned to word boundaries. Converting a float* to int* and
dereferencing it causes UB if the float* points anywhere else than
to the beginning of a 4-byte word.
>>2) I've seen code like the following:

struct s {
int a;
char *b;
float c;
} s;
int *i = (int *) s;

Isn't this undefined?
[snip]
I think if you check, the compiler is allowed to insert padding
into
structs as it sees fit. In particular, if the address of s isn't
properly aligned for an int then it will have to insert padding!
The standard explicitly require that a pointer to a struct can point to
its first member if converted to its type.

--
Army1987 (Replace "NOSPAM" with "email")
If you're sending e-mail from a Windows machine, turn off Microsoft's
stupid “Smart Quotes” feature. This is so you'll avoid sprinkling garbage
characters through your mail. -- Eric S. Raymond and Rick Moen

Sep 9 '07 #7
Tommy Vercetti wrote:
On 8 Sep 2007 at 22:45, Harald van Dijk wrote:
>Tommy Vercetti wrote:
>>Hi -

Great group!

I have 2 queries about undefined behavior:

1) Is the following code undefined?

float myfunction(floa t f)
{
if(sizeof(float ) & sizeof(int)) {

I've tried figuring out why you would use the & operator here. I'm not
seeing it. Did you mean to use != ?

It's an optimization - at the machine code level, most processors will
have a single instruction for &.
And most processors will also have a single instruction for !=. This is
irrelevant though, since sizeof(float) and sizeof(int) are constants, and
the compiler is required to be able to evaluate the expression at compile
time. It would take a particularly perverse compiler to not actually do so.
Sep 9 '07 #8
On 2007-09-09 08:10, Tommy Vercetti <no@spam.comwro te:
On 8 Sep 2007 at 22:45, Harald van Dijk wrote:
>Tommy Vercetti wrote:
>>Hi -

Great group!

I have 2 queries about undefined behavior:

1) Is the following code undefined?

float myfunction(floa t f)
{
if(sizeof(float ) & sizeof(int)) {

I've tried figuring out why you would use the & operator here. I'm not
seeing it. Did you mean to use != ?

It's an optimization -
No, it's simply wrong.

Consider the (common) case of sizeof(float) == sizeof(int) == 4:
4 & 4 == 4, so the then branch (slow ordinary FP operations) is
executed. This is almost certainly not what you wanted.

If sizeof(int) == 8 and sizeof(float) == 4, (4 & 8) == 0, so the else
branch (int i = *(int *)&f) is executed, which causes undefined
behaviour due to the possible alignment mismatch.

But you haven't just reversed the test: If for example sizeof(int) == 8
and sizeof(float) == 12, then it will still test as true.

at the machine code level, most processors will
have a single instruction for &.
At the machine code level, most processors also have single instructions
for comparing integers. But most likely, the test will never be made at
runtime because it can already be evaluated at compile time.

Morals: Write what you mean and let the compiler worry about
optimization.
>
>> /* use slow ordinary FP operations */
} else {
int i = *(int *)&f;
/* do clever bit-twiddling floating-point operation */
}
}

It only attempts to access the float as an integer when this makes
sense.
Actually, it only attempts to access the float as an integer when this
makes no sense. But assuming you got the test right: I think this is
still undefined behaviour:

1) Even if the size is the same, the alignment can be different (think
of the old x86 series, where integer and fp unit were separate
processors: They could easily have had different alignment
requirements).

2) Even if the alignment is the same, reinterpreting an fp number as an
int is not defined. The bit pattern can represent a trap value, for
example.

And thirdly, knowing the size is not enough for "clever bit-twiddling".
You need to know the representation. So that code should be something
like:
#if __STDC_IEC_559_ _ && CLEVER_BIT_TWID DLING_IS_FASTER
/* clever bit twiddling here */
#else
/* normal FP here
#endif

Even though the undefined-behavior lines aren't called in situations
where they'd be undefined?
No, but in your code the undefined-behavior will be called. Your checks
to prevent that are insufficient.
E.g. in the following code:

if(1==2) {
char *p=NULL;
*p; /* KABOOM! */
}
That's ok.

>>Won't this blow up if the compiler inserts padding
before the first element of the struct?

Right. Which is not a problem, since the compiler is not allowed to insert
padding before the first element of the struct.

I think if you check, the compiler is allowed to insert padding into
structs as it sees fit. In particular, if the address of s isn't
properly aligned for an int then it will have to insert padding!
No, it will have to ensure that s is properly aligned for all its
members.

hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hj*@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
Sep 9 '07 #9
Tommy Vercetti wrote:
Harald van Dijk wrote:
>Tommy Vercetti wrote:
.... snip ...
>>>
struct s {
int a;
char *b;
float c;
} s;
int *i = (int *) &s; /* & added - cbf */
.... snip ...
>
>>Won't this blow up if the compiler inserts padding
before the first element of the struct?

Right. Which is not a problem, since the compiler is not allowed
to insert padding before the first element of the struct.

I think if you check, the compiler is allowed to insert padding into
structs as it sees fit. In particular, if the address of s isn't
properly aligned for an int then it will have to insert padding!
But not before the first item in a struct. The struct won't be
assigned any address that is not suitable for an int.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 9 '07 #10

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

Similar topics

48
3043
by: marbac | last post by:
Hi, i heard a lot about "undefined behaviour" in this and other newsgroups dealing with c/c++. Is there a list where all cases with undefined behaviour in C++ are listed? regards marbac
19
2560
by: E. Robert Tisdale | last post by:
In the context of the comp.lang.c newsgroup, the term "undefined behavior" actually refers to behavior not defined by the ANSI/ISO C 9 standard. Specifically, it is *not* true that "anything can happen" if your C code invokes "undefined behavior". Behavior not defined by the ANSI/ISO C 9 standard may be defined by some other standard (i.e....
66
3013
by: Mantorok Redgormor | last post by:
#include <stdio.h> struct foo { int example; struct bar *ptr; }; int main(void) { struct foo baz; baz.ptr = NULL; /* Undefined behavior? */ return 0;
25
3076
by: Nitin Bhardwaj | last post by:
Well, i'm a relatively new into C( strictly speaking : well i'm a student and have been doing & studying C programming for the last 4 years).....and also a regular reader of "comp.lang.c" I don't have a copy of ANSI C89 standard,therefore i had to post this question: What is the difference between "unspecified" behaviour & "undefined"...
30
22707
by: jimjim | last post by:
Hello, #include <stdio.h> int main(int argc, char *argv) { int x = 1; printf("%d %d %d\n", ++x, x, x++); return 0; }
33
2308
by: dragoncoder | last post by:
Hi all, Does the following code invoke undefined behaviour ? $ cat a1.cc #include <iostream> #include <limits> int main() { int a = INT_MAX/2;
14
2557
by: avsharath | last post by:
In "Bjarne Stroustrup's C++ Style and Technique FAQ" at: http://www.research.att.com/~bs/bs_faq2.html#evaluation-order for the statement: f(v,i++); he says that "the result is undefined because the order of evaluation of function arguments are undefined". But AFAIK, the order of evaluation of function arguments is unspecified
12
3038
by: Rajesh S R | last post by:
Can anyone tell me what is the difference between undefined behavior and unspecified behavior? Though I've read what is given about them, in ISO standards, I'm still not able to get the difference. For example: Consider the following code: a = i; We say that the above expression statement produces undefined
33
2804
by: coolguyaroundyou | last post by:
Will the following statement invoke undefined behavior : a^=b,b^=a,a^=b ; given that a and b are of int-type ?? Be cautious, I have not written a^=b^=a^=b ; which, of course, is undefined. I am having some confusion with the former statement! Also, state the reason for the statement being undefined!
0
7693
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, well explore What is ONU, What Is Router, ONU & Routers main...
0
7604
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...
1
7660
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
6275
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing, and deploymentwithout human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5498
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...
0
5217
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...
1
2101
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
1
1207
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
932
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...

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.