473,387 Members | 1,574 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,387 software developers and data experts.

Aliasing bug when casting char[] into char* ?

Hi folks,

I have a probably rather silly question: is casting a char array in a
char* a potential source of aliasing bug ?

Example: a fonction returning a buffer taken in a circular buffer

typedef struct foo_t foo_t;
struct foo_t {
int index;
char buff[16][8192];
};

static char* getBuff(foo_t *s) {
s->index = ( s->index + 1 ) % 16;
printf("returning s->buff[%d] == %p\n",
s->index, s->buff[s->index]);
return s->buff[s->index];
}

void test(char *a, char *b) {
printf("got pointers: %p %p\n", a, b);
}

int main(void) {
foo_t s = { 0 };
test(getBuff(&s), getBuff(&s));
return 0;
}

The problem is that on Visual C++ 2003, the two returned pointers are
identical when optimizing (!)

Tested with Visual C++ 2003, release mode (optimized)

returning s->buff[1] == 00111F5C
returning s->buff[2] == 00113F5C
got pointers: 00113F5C 00113F5C

Tested with gcc 3.3.4, optimized (O4):

returning s->buff[1] == 0xfffde008
returning s->buff[2] == 0xfffe0008
got pointers: 0xfffde008 0xfffe0008

Is the bug inside this code ? (or inside the compiler ?)

Feb 6 '07 #1
4 2131
On Feb 6, 10:17 pm, Xavier Roche <xro...@free.fr.NOSPAM.invalid>
wrote:
Hi folks,

I have a probably rather silly question: is casting a char array in a
char* a potential source of aliasing bug ?
I'm not sure what you mean, I don't see any casts in your code.
>
Example: a fonction returning a buffer taken in a circular buffer
#include <stdio.h>
>
typedef struct foo_t foo_t;
struct foo_t {
int index;
char buff[16][8192];
};

static char* getBuff(foo_t *s) {
s->index = ( s->index + 1 ) % 16;
printf("returning s->buff[%d] == %p\n",
s->index, s->buff[s->index]);
When using %p, the argument must be a pointer to void, so you need an
explicit cast here:
(void *)s->buff[s->index]
return s->buff[s->index];
}

void test(char *a, char *b) {
printf("got pointers: %p %p\n", a, b);
Same as above, a missing (void *) cast.
}

int main(void) {
foo_t s = { 0 };
test(getBuff(&s), getBuff(&s));
The order of evaluation is unspecified for function arguments, so
don't use it like this. Better:
char *p1 = getBuff (&s);
char *p2 = getBuff (&s);
test (p1, p2);
return 0;
}

The problem is that on Visual C++ 2003, the two returned pointers are
identical when optimizing (!)
I'm probably missing something here, but someone else will point out
the (obvious) problem. I suggest you fix the above problems first and
see if it helps.
<snip>
--
WYCIWYG - what you C is what you get

Feb 6 '07 #2
Xavier Roche wrote On 02/06/07 16:17,:
Hi folks,

I have a probably rather silly question: is casting a char array in a
char* a potential source of aliasing bug ?

Example: a fonction returning a buffer taken in a circular buffer

typedef struct foo_t foo_t;
struct foo_t {
int index;
char buff[16][8192];
};

static char* getBuff(foo_t *s) {
s->index = ( s->index + 1 ) % 16;
printf("returning s->buff[%d] == %p\n",
s->index, s->buff[s->index]);
return s->buff[s->index];
}

void test(char *a, char *b) {
printf("got pointers: %p %p\n", a, b);
}

int main(void) {
foo_t s = { 0 };
test(getBuff(&s), getBuff(&s));
return 0;
}

The problem is that on Visual C++ 2003, the two returned pointers are
identical when optimizing (!)

Tested with Visual C++ 2003, release mode (optimized)

returning s->buff[1] == 00111F5C
returning s->buff[2] == 00113F5C
got pointers: 00113F5C 00113F5C

Tested with gcc 3.3.4, optimized (O4):

returning s->buff[1] == 0xfffde008
returning s->buff[2] == 0xfffe0008
got pointers: 0xfffde008 0xfffe0008

Is the bug inside this code ? (or inside the compiler ?)
It looks like the compiler is at fault (or else I've
missed something). The two pointers could appear in either
order in the "got pointers" line because the compiler can
choose to evaluate the `a' argument either before or after
the `b' argument, but no matter which order it chooses the
two printed values should be different.

--
Er*********@sun.com
Feb 6 '07 #3
On Feb 7, 10:17 am, Xavier Roche <xro...@free.fr.NOSPAM.invalid>
wrote:
static char* getBuff(foo_t *s) {
s->index = ( s->index + 1 ) % 16;
printf("returning s->buff[%d] == %p\n",
s->index, s->buff[s->index]);
return s->buff[s->index];
}

void test(char *a, char *b) {
printf("got pointers: %p %p\n", a, b);
}

int main(void) {
foo_t s = { 0 };
test(getBuff(&s), getBuff(&s));
return 0;
}

Tested with Visual C++ 2003, release mode (optimized)

returning s->buff[1] == 00111F5C
returning s->buff[2] == 00113F5C
got pointers: 00113F5C 00113F5C
Has to be a compiler bug. I wonder if you could inspect the
assembly code generated, and see what it is actually
doing. Does it make any difference if you remove the
'static' keyword? (Not that it should, but perhaps the
compiler is getting confused).

Also, check that the compiler is in ISO C++ compliance
mode (if it has one!); some compilers have optimization
switches that violate the standard (ie. make assumptions
that are not guaranteed).

Feb 6 '07 #4
Xavier Roche <xro...@free.fr.NOSPAM.invalidwrote:
Hi folks,

I have a probably rather silly question: is casting a char array in a
char* a potential source of aliasing bug ?

Example: a fonction returning a buffer taken in a circular buffer
I don't see a #include <stdio.hheader anywhere.

If that's missing then you don't have a prototype for the variadic
function
printf. Which means the behaviour is undefined.
typedef struct foo_t foo_t;
struct foo_t {
int index;
char buff[16][8192];
This means the struct is at least 131072 bytes. This exceeds the
minimum
required implementation limit of 32767 bytes of an object in C90.

What happens if you make the buffers smaller...?

char buff[16][16];

I suggest you allocate the buffers dynamically.
};

static char* getBuff(foo_t *s) {
s->index = ( s->index + 1 ) % 16;
printf("returning s->buff[%d] == %p\n",
s->index, s->buff[s->index]);
Although char * and void * are required to have the same
representation,
you're best of converting the second parameter to void * as required
by
%p.
return s->buff[s->index];

}

void test(char *a, char *b) {
printf("got pointers: %p %p\n", a, b);
Ditto.
>
}

int main(void) {
foo_t s = { 0 };
test(getBuff(&s), getBuff(&s));
return 0;
}

The problem is that on Visual C++ 2003, the two returned pointers are
identical when optimizing (!)

Tested with Visual C++ 2003, release mode (optimized)

returning s->buff[1] == 00111F5C
returning s->buff[2] == 00113F5C
got pointers: 00113F5C 00113F5C

Tested with gcc 3.3.4, optimized (O4):

returning s->buff[1] == 0xfffde008
returning s->buff[2] == 0xfffe0008
got pointers: 0xfffde008 0xfffe0008
--
Peter
Feb 7 '07 #5

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

Similar topics

5
by: dis | last post by:
I've been going through my code and clearing away some of the compiler warnings that i'm generating and i've come across areas where i cast pointers to integer values. The Visual Studio compiler...
2
by: Hakan | last post by:
Is static_cast<void*>( const_cast<char*>( p )) the correct construction for casting a const char* p to a void* p? TIA.
9
by: M Welinder | last post by:
This doesn't work with any C compiler that I can find. They all report a syntax error: printf ("%d\n", (int)sizeof (char)(char)2); Now the question is "why?" "sizeof" and "(char)" have...
3
by: Matt | last post by:
Hi, Recently we had some code like this cause a failure: MyEnum myEnum = (MyEnum) (int) dt; i.e. reading an int out of the database and casting it into a type-safe enum. The thought...
1
by: themaxmail | last post by:
Hi I am a c++ begginner, and I apologyse myself if my question will be stupid :-P In the program I am writing I have memory space problem and I decided to store an 5 dymension array storing...
8
by: vsgdp | last post by:
On Windows XP, unsigned integers are 32 bits. Partition the bits of the unsigned integer C into 4 8-bit chunks like so: C = XRGB. Then unsigned char* p = &C; Does
8
by: Gamma | last post by:
I'm trying to inherit subclass from System.Diagnostics.Process, but whenever I cast a "Process" object to it's subclass, I encounter an exception "System.InvalidCastException" ("Specified cast is...
1
by: Xavier Roche | last post by:
Hi folks, I have a probably rather silly question: is casting a char array in a char* a potential source of aliasing bug ? Example: a fonction returning a buffer taken in a circular buffer ...
5
by: rolan | last post by:
I am writing a program in c++ using fluid with the FLTK libraries. I have a text_input widget in my main window, and when I try to access the value in the widget it returns a const char*. I need...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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...
0
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,...
0
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...

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.