Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Is the behaviour defined (http://www.velocityreviews.com/forums/t439619-is-the-behaviour-defined.html)

grid 10-01-2005 01:51 PM

Is the behaviour defined
 
Hi,
A collegue of mine is of the opinion that the behaviour of the
following program is defined,but I am a little apprehensive.

#include<stdio.h>
#include<string.h>

int main()
{
char *c;
c = &c;
strcpy(c,"abc");
puts(&c);
retun 0;
}

The program prints the same value "abc" on multiple platforms and I even
tried it with multiple compilers.I can make out that its trying to write
to the pointer address and so probably the max it can write is 3 bytes +
'\0'.But even if I try to copy more that 4 bytes it prints the whole
string without any crashes.

Changed line >> strcpy(c,"abcdefg");

Now I know that this behaviour is undefined(writing more than 4 bytes)
as the sizeof the pointer is 4 bytes(on the machine I tested on).

Can anyone comment if this is compliant code and is the behaviour
guaranteed.

Thanks
~

grid 10-01-2005 01:55 PM

Re: Is the behaviour defined
 
> int main()
> {
> char *c;
> c = &c;
> strcpy(c,"abc");
> puts(&c);
> retun 0;
> }

It should be return 0;
The spell of the return is wrong in the test program above.I did not
have it in my test program which I compiled , but added it while
composing this mail , of the fear of getting battered by the C language
purists ;).

Emmanuel Delahaye 10-01-2005 02:09 PM

Re: Is the behaviour defined
 
grid wrote on 01/10/05 :
> A collegue of mine is of the opinion that the behaviour of the following
> program is defined,


At minimum, it's implementation-dependent. But the result of putting
any value in a pointer may have an undefined result (trap
representation). There is a possibility of undefined behaviour.

> but I am a little apprehensive.


You can!

> #include<stdio.h>
> #include<string.h>
>
> int main()
> {
> char *c;
> c = &c;


Types are incompatible. (c is a char * and &c is a char**)

> strcpy(c,"abc");


The result of the 'sizeof char* == sizeof "abc"' expression is
implementation-dependent.

You need a space of 4 bytes for "abc".

For example, on a x86 in real mode (16-bit) model small, pointers are
16-bit wide, which means 2 bytes on this machine. Too small for "abc"

> puts(&c);
> retun 0;
> }


--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

..sig under repair



Alexei A. Frounze 10-01-2005 02:12 PM

Re: Is the behaviour defined
 
"grid" <prohit99@gmail.com> wrote in message
news:QKw%e.3$xh3.88@news.oracle.com...
> A collegue of mine is of the opinion that the behaviour of the
> following program is defined,but I am a little apprehensive.
>
> #include<stdio.h>
> #include<string.h>
>
> int main()
> {
> char *c;
> c = &c;
> strcpy(c,"abc");
> puts(&c);
> retun 0;
> }


The above code is broken. You attempt to store 4 chars/bytes
(1+strlen("abc")==4) to the variable c, but you don't know whether c
(pointer to a char) is big enough to hold 4 chars/bytes. On some platforms
it can be 2 or even 1, hence you're risking to overwrite something else.
Tell your collegue first to learn C better before advising a code such as
the above.

Alex



grid 10-01-2005 02:22 PM

Re: Is the behaviour defined
 
>> char *c;
>> c = &c;

>
>
> Types are incompatible. (c is a char * and &c is a char**)


That is just to make c point to the first byte of the string.We will
anyhow require a cast for this to silence the compiler, since they are
really incompatible types as you mentioned

c = (char *)&c;

Thanks,
~

Emmanuel Delahaye 10-01-2005 02:24 PM

Re: Is the behaviour defined
 
grid wrote on 01/10/05 :
>>> char *c;
>>> c = &c;

>>
>> Types are incompatible. (c is a char * and &c is a char**)

>
> That is just to make c point to the first byte of the string.We will anyhow
> require a cast for this to silence the compiler, since they are really
> incompatible types as you mentioned
>
> c = (char *)&c;


The result of the cast is implementation-dependent.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

..sig under repair



grid 10-01-2005 02:30 PM

Re: Is the behaviour defined
 
> The above code is broken. You attempt to store 4 chars/bytes
> (1+strlen("abc")==4) to the variable c, but you don't know whether c
> (pointer to a char) is big enough to hold 4 chars/bytes. On some platforms
> it can be 2 or even 1, hence you're risking to overwrite something else.


I gave the example for my particular machine/hardware just to make it a
point that this might not be a portable code.But apart from that, is it
guaranteed to function as intended where the pointer sizes are 4 bytes
or more.

Also writing past 4 bytes on a machine with 4 byte pointers dosent seem
to affect,though I am aware that undefined behaviour can really be
anything and that could also mean that it dosent manifests itself at
all.But this kind of non-compliant behaviour probably compels people to
write non-portable code in the first place rather than any significant
gain in efficiancy.

Thanks
~

Alexei A. Frounze 10-01-2005 05:12 PM

Re: Is the behaviour defined
 
"grid" <prohit99@gmail.com> wrote in message
news:Fjx%e.6$xh3.62@news.oracle.com...
> > The above code is broken. You attempt to store 4 chars/bytes
> > (1+strlen("abc")==4) to the variable c, but you don't know whether c
> > (pointer to a char) is big enough to hold 4 chars/bytes. On some

platforms
> > it can be 2 or even 1, hence you're risking to overwrite something else.

>
> I gave the example for my particular machine/hardware just to make it a
> point that this might not be a portable code.


It's not portable. It's portable around your machine's hard drive, but not
much further :) Or you should probably ask such portability and undefined
behavior questions at comp.lang.c.x86 or something like that :)

> But apart from that, is it
> guaranteed to function as intended where the pointer sizes are 4 bytes
> or more.


I see no good reason for such code to exist at first place. Perhaps you
could tell me it, if there is.
It's much more easier and portable to declare a local 4-char array. If you
need to use that space either for a pointer or for an array of 4 chars (one
of them at a time), there's a union keyword for that.

> Also writing past 4 bytes on a machine with 4 byte pointers dosent seem
> to affect,though I am aware that undefined behaviour can really be
> anything and that could also mean that it dosent manifests itself at
> all.But this kind of non-compliant behaviour probably compels people to
> write non-portable code in the first place rather than any significant
> gain in efficiancy.


Unportable code is the result of not following the standard (usually not
knowning anything about it and not reading good books that were written with
the standard in mind or not paying attention to those important details) but
instead making own assumptions and relying on something that might or might
not be true. If there's a need for any hardware/CPU-specific code, the
proper way of doing it is to define the API and put portable code on one
side of it and that platform specific code on the other side and never move
a tiny bit of it to the portable part. Unportable code is mixing portable
things with non-portable. Often times those non-portable things are due to
writing say 4 when it must be sizeof(int) or sizeof(int*), improperly
aligning data, improperly calculating sizes of structures and offsets of
their members, reading/writing integers as bytes with big/little endian
problems, ignoring casting to long in multiplication of ints (ignoring the
fact that int and long aren't necessarily types of the same physical size),
etc. The thing is, many books don't mention many practical things and hence
the programmer must invent some way to them, often a quick and durty
non-portable hack.

Alex



Flash Gordon 10-01-2005 06:31 PM

Re: Is the behaviour defined
 
Emmanuel Delahaye wrote:
> grid wrote on 01/10/05 :
>
>>>> char *c;
>>>> c = &c;
>>>
>>> Types are incompatible. (c is a char * and &c is a char**)

>>
>> That is just to make c point to the first byte of the string.We will
>> anyhow require a cast for this to silence the compiler, since they are
>> really incompatible types as you mentioned
>>
>> c = (char *)&c;

>
> The result of the cast is implementation-dependent.


Surely it is defined as producing a pointer to the first byte of c? If
it was *not* (char*), (unsigned char*) or (signed char*) I would agree
with you.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.

Keith Thompson 10-01-2005 06:31 PM

Re: Is the behaviour defined
 
grid <prohit99@gmail.com> writes:
>> int main()
>> {
>> char *c;
>> c = &c;
>> strcpy(c,"abc");
>> puts(&c);
>> retun 0; }

> It should be return 0;
> The spell of the return is wrong in the test program above.I did not
> have it in my test program which I compiled , but added it while
> composing this mail , of the fear of getting battered by the C
> language purists ;).


This is why you should *always* copy-and-paste the actual code that
you fed to the compiler, rather than re-typing it.

--
Keith Thompson (The_Other_Keith) kst-u@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.


All times are GMT. The time now is 07:26 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.