Hello. I found a problem in the way that some C compilers handle
the case where a function modifies a global pointer and returns
an address which is assigned to that same global pointer.
A test program appears below. The following compilers are able
to generate a code which can take branch #1 of the test program
without any problems:
HP-UX bundled C (K&R) \
HP-UX ANSI-C > all 11.x releases on all platforms
HP-UX aCC (C++) /
Microsoft C (Visual Studio 2008)
gcc-2.95
The compilers that fail the branch #1 test are:
gcc 3.x
gcc 4.x
Compaq C V6.5-011 on HP Tru64 UNIX V5.1B (Rev. 2650)
Could any of you who have access to Sun's Studio C compiler
please compile the test program and post the results?
Thanks,
Andris
....................................................................
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define PC struct pc
typedef unsigned short word;
PC { /* typical linked list structure */
word op;
PC *code;
};
PC *pcptr; /* global structures */
PC *pcptr_copy;
#ifdef __STDC__
int get_data(char *prompt)
#else
int get_data(prompt)
char *prompt;
#endif
{
char buf[40];
int result, *result_ptr;
result_ptr = &result;
do {
fputs(prompt, stdout);
fgets(buf, sizeof(buf), stdin);
sscanf(buf, "%i", result_ptr);
} while (result != 1 && result != 2);
return(result);
}
#ifdef __STDC__
PC *fnc_A(void)
#else
PC *fnc_A()
#endif
{
if ((pcptr = pcptr_copy = (PC *)malloc(sizeof(PC))) == NULL) {
perror("malloc(3) failed");
exit(1);
}
pcptr->code = NULL;
printf("fnc_A: \tpcptr = %p\n", (void *)pcptr);
printf(" \tpcptr->code = %p\n", (void *)pcptr->code);
return(pcptr);
}
#ifdef __STDC__
int main(void)
#else
int main()
#endif
{
int init_choice, branch;
branch = get_data("Take the suspect branch [1] or stay
`safe' [2]? ");
init_choice = get_data("Initialize `pcptr' with NULL [1] or malloc
[2]? ");
puts("");
if (init_choice == 1)
pcptr = NULL;
else {
if ((pcptr = (PC *)malloc(sizeof(PC))) == NULL) {
perror("malloc(3) failed");
exit(1);
}
}
printf("main: [init] pcptr = %p\n\n", (void *)pcptr);
printf("Taking branch %i.\n", branch);
if (branch == 1)
/*
* This branch works fine with the gcc-2.95 and HP-UX
compilers.
* If compiled with gcc {3,4}.X, however, the results are:
*
* > SEGFAULT if `pcptr' is initialized to NULL
* or
* > Corrupted value of `pcptr->code' if `pcptr'
* is initialized to a non-NULL address.
*
* The newer compilers appear to incorrectly handle the case
* where the assignment target is a global pointer reference
* (pcptr->code) and the value being assigned is returned by
* a function which can modify the global pointer itself.
*/
pcptr->code = fnc_A();
else {
/*
* All compilers can handle this branch correctly
* regardless of how `pcptr' is initialized.
*/
PC *tmp_ptr;
tmp_ptr = fnc_A();
pcptr->code = tmp_ptr;
}
printf("main: \tpcptr = %p", (void *)pcptr);
printf("\t(%p <- should be this)\n", (void *)pcptr_copy);
printf(" \tpcptr->code = %p", (void *)pcptr->code);
printf("\t(%p <- should be this)\n", (void *)pcptr_copy);
return(0);
}
|
|
0
|
|
|
|
Reply
|
andris (2)
|
1/11/2010 3:29:41 AM |
|
Andris K, wrote:
> Hello. I found a problem in the way that some C compilers handle
> the case where a function modifies a global pointer and returns
> an address which is assigned to that same global pointer.
> A test program appears below. The following compilers are able
> to generate a code which can take branch #1 of the test program
> without any problems:
>
> HP-UX bundled C (K&R) \
> HP-UX ANSI-C > all 11.x releases on all platforms
> HP-UX aCC (C++) /
> Microsoft C (Visual Studio 2008)
> gcc-2.95
>
> The compilers that fail the branch #1 test are:
>
> gcc 3.x
> gcc 4.x
> Compaq C V6.5-011 on HP Tru64 UNIX V5.1B (Rev. 2650)
>
> Could any of you who have access to Sun's Studio C compiler
> please compile the test program and post the results?
>
I don't think much of the code, but it runs fin when compiled with cc:
> c99 /tmp/x.c
> ./a.out
Take the suspect branch [1] or stay`safe' [2]? 1
Initialize `pcptr' with NULL [1] or malloc[2]? 1
main: [init] pcptr = 0
Taking branch 1.
fnc_A: pcptr = 8061638
pcptr->code = 0
main: pcptr = 8061638 (8061638 <- should be this)
pcptr->code = 8061638 (8061638 <- should be this)
--
Ian Collins
|
|
0
|
|
|
|
Reply
|
Ian
|
1/11/2010 4:23:36 AM
|
|
On Jan 10, 8:23=A0pm, Ian Collins <ian-n...@hotmail.com> wrote:
> Andris K, wrote:
> > Hello. =A0I found a problem in the way that some C compilers handle
> > the case where a function modifies a global pointer and returns
> > an address which is assigned to that same global pointer.
> > A test program appears below. =A0The following compilers are able
> > to generate a code which can take branch #1 of the test program
> > without any problems:
>
> > =A0 HP-UX bundled C (K&R) =A0\
> > =A0 HP-UX ANSI-C =A0 =A0 =A0 =A0 =A0 =A0> all 11.x releases on all plat=
forms
> > =A0 HP-UX aCC (C++) =A0 =A0 =A0 =A0/
> > =A0 Microsoft C (Visual Studio 2008)
> > =A0 gcc-2.95
>
> > The compilers that fail the branch #1 test are:
>
> > =A0 gcc 3.x
> > =A0 gcc 4.x
> > =A0 Compaq C V6.5-011 on HP Tru64 UNIX V5.1B (Rev. 2650)
>
> > Could any of you who have access to Sun's Studio C compiler
> > please compile the test program and post the results?
>
> I don't think much of the code, but it runs fin when compiled with cc:
>
> =A0> c99 /tmp/x.c
> =A0> ./a.out
> Take the suspect branch [1] or stay`safe' [2]? 1
> Initialize `pcptr' with NULL [1] or malloc[2]? 1
>
> main: =A0 =A0[init] pcptr =A0 =A0 =A0 =3D 0
>
> Taking branch 1.
> fnc_A: =A0 =A0 =A0 =A0pcptr =A0 =A0 =A0 =3D 8061638
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0pcptr->code =3D 0
> main: =A0 =A0 =A0 =A0 pcptr =A0 =A0 =A0 =3D 8061638 =A0 (8061638 <- sho=
uld be this)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0pcptr->code =3D 8061638 =A0 (8061638 <=
- should be this)
Thanks, Ian. The legacy code (early 90's) from which this test was
derived is, unfortunately, what it is. I'm glad to see that Sun's
compiler
could handle this particular situation.
------
Andris
|
|
0
|
|
|
|
Reply
|
Andris
|
1/11/2010 5:20:51 AM
|
|
Andris K, wrote:
>
> Thanks, Ian. The legacy code (early 90's) from which this test was
> derived is, unfortunately, what it is. I'm glad to see that Sun's
> compiler
> could handle this particular situation.
I think the line
pcptr->code = fnc_A();
exhibits undefined behaviour. Try posting the code to comp.lang.c and
see what they have to say.
--
Ian Collins
|
|
0
|
|
|
|
Reply
|
Ian
|
1/11/2010 6:27:31 AM
|
|
On Jan 10, 10:27=A0pm, Ian Collins <ian-n...@hotmail.com> wrote:
> Andris K, wrote:
>
> > Thanks, Ian. =A0The legacy code (early 90's) from which this test was
> > derived is, unfortunately, what it is. =A0I'm glad to see that Sun's
> > compiler
> > could handle this particular situation.
>
> I think the line
>
> pcptr->code =3D fnc_A();
>
> exhibits undefined behaviour. =A0Try posting the code to comp.lang.c and
> see what they have to say.
>
> --
> Ian Collins
Will do. I'm in the midst of trying to convince the gcc folks that
their
failure to handle this situation is a defect. I've made a similar
test
request to comp.unix.aix to see if the IBM compilers behave like the
Sun, HP-UX, and Microsoft compilers. I'll certainly consider the
advice
of the experts in comp.lang.c.
------
Andris
community
|
|
0
|
|
|
|
Reply
|
Andris
|
1/11/2010 8:12:40 AM
|
|
On 2010-01-11 06:27:31 +0000, Ian Collins <ian-news@hotmail.com> said:
> I think the line
>
> pcptr->code = fnc_A();
>
> exhibits undefined behaviour. Try posting the code to comp.lang.c and
> see what they have to say.
I'm pretty sure it does as well.
|
|
0
|
|
|
|
Reply
|
Tim
|
1/11/2010 8:23:58 PM
|
|
|
5 Replies
241 Views
(page loaded in 0.104 seconds)
|