473,942 Members | 16,704 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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,"abcde fg");

Now I know that this behaviour is undefined(writi ng 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
~
Nov 15 '05
31 1400
Old Wolf wrote:
#include <stdio.h>
#include <string.h>

int main(void)
{
if ( sizeof(char *) >= sizeof "abc" )
{
char *c;
c = (char *)&c;
strcpy(c,"abc") ;
puts(&c);
Of course I meant:
puts( (char *)&c );
}
return 0;
}


Nov 15 '05 #21
"Old Wolf" <ol*****@inspir e.net.nz> writes:
Old Wolf wrote:
#include <stdio.h>
#include <string.h>

int main(void)
{
if ( sizeof(char *) >= sizeof "abc" )
{
char *c;
c = (char *)&c;
strcpy(c,"abc") ;
puts(&c);
Of course I meant:
puts( (char *)&c );


Or just
puts(c);
}
return 0;
}


--
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.
Nov 15 '05 #22
Joe Wright (jw*****@comcas t.net) wrote:
: grid wrote:
: >> 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 ;).

: Let me be the first to warn of impending doom. You define c an object of
: type char*. For sake of argument, the compiler arbitrarily places c at
: address 0100. Now you assign this address to c itself. If your warnings
: are high enough, you will be told about this. c has type char* while &c
: has type char**. The two are incompatible types.

: Assuming you got away with the assingment 'c = &c;' your c doesn't point
: to usable memory.
"c doesn't point to usable memory"

No, c is on the stack and so &c is pointing at one end of the free space
on the stack.

This sort of trick would be seen in code such as an operating system.
The idea is to get the current address of the top of the stack so as to
"malloc" yourself some memory from the stack without using a memory
manager. If you want to use C instead of assembler to manipulate what
goes on inside the computer then you may need to use that sort of trick,
just like when you point your C variables at hard coded video address or
port addresses, etc.

In this case though, the call to strcpy is very problematic because strcpy
will be using that same area of the stack for its call frame. So in the
above there is a possibility of corrupting the stack. I think exactly one
byte can be safely written since we don't know in general which direction
the stack grows, or the endianess of the pointer.

In assembler you would commonly do the equivalent to the above, (take the
address of the memory which is the stack), but you would then move the
stack pointer before using the memory.

That is exactly what the old malloc variant "alloca()" did, but I don't
recall seeing that call available in any modern system.

It certainly isn't good for any normal application to do this trickery.

$0.10

--

This programmer available for rent.
Nov 15 '05 #23

In article <43********@new s.victoria.tc.c a>, yf***@vtn1.vict oria.tc.ca (Malcolm Dew-Jones) writes:

No, c is on the stack and so &c is pointing at one end of the free space
on the stack.
&c points to the first byte of the contents of c. Nothing more is
guaranteed by the language.

The C language does not require a "stack" in this sense (a contiguous
area of memory from which automatic variables, and other things, can
be allocated). It requires some stack-equivalent mechanism to
support the function-call semantics, but that can be, for example,
chained activation records.

There need not be any "free space" adjacent to any automatic
variable, and the implementation certainly need not allow the program
access to it.
I think exactly one
byte can be safely written since we don't know in general which direction
the stack grows, or the endianess of the pointer.


There are conforming implementations where this is not true.

As Old Wolf noted, C guarantees that we can inspect and alter the
contents of the "c" variable using a character pointer. It does not
guarantee that we can do anything outside the extent of that object
using a pointer to it; in fact, any such access invokes undefined
behavior.

--
Michael Wojcik mi************@ microfocus.com

Cooperation is just like two pagodas, one hardware and one software.
-- Wen Jiabao
Nov 15 '05 #24
Michael Wojcik (mw*****@newsgu y.com) wrote:

: In article <43********@new s.victoria.tc.c a>, yf***@vtn1.vict oria.tc.ca (Malcolm Dew-Jones) writes:
: >
: > No, c is on the stack and so &c is pointing at one end of the free space
: > on the stack.

: &c points to the first byte of the contents of c. Nothing more is
: guaranteed by the language.

Well I agree, I didn't mean to imply that the language required what I
described, only that the idiom of taking the address of an auto variable
is not some thoughtless bug, but is a real technique used in situations
when the alternative might be assembler language or FORTH or such like.

Nov 15 '05 #25
Keith Thompson wrote:
"Old Wolf" <ol*****@inspir e.net.nz> writes:
Old Wolf wrote:
#include <stdio.h>
#include <string.h>

int main(void)
{
if ( sizeof(char *) >= sizeof "abc" )
{
char *c;
c = (char *)&c;
strcpy(c,"abc") ;
puts(&c);


Of course I meant:
puts( (char *)&c );

Or just
puts(c);

}
return 0;
}



No. puts(c); will probably segfault (it does here) because c is neither
an array nor a pointer. This seems to "work"..

#include <stdio.h>
#include <string.h>
int main(void) {
char *c;
c = (char*)&c;
strcpy(c, "abc");
puts((char*)&c) ;
return 0;
}

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 15 '05 #26
Joe Wright <jw*****@comcas t.net> writes:
Keith Thompson wrote:
"Old Wolf" <ol*****@inspir e.net.nz> writes:
Old Wolf wrote:

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

int main(void)
{
if ( sizeof(char *) >= sizeof "abc" )
{
char *c;
c = (char *)&c;
strcpy(c,"abc") ;
puts(&c);

Of course I meant:
puts( (char *)&c );

Or just
puts(c);
}
return 0;
}


No. puts(c); will probably segfault (it does here) because c is
neither an array nor a pointer. This seems to "work"..

#include <stdio.h>
#include <string.h>
int main(void) {
char *c;
c = (char*)&c;
strcpy(c, "abc");
puts((char*)&c) ;
return 0;
}


A quibble: Yes, c is a pointer object, since it's declared as
"char *c;". But you're right, it doesn't contain a valid pointer
value; it contains the bytes 'a', 'b', 'c', and '\0' (plus other
garbage if sizeof(char*)>4 ). I was thrown off by the fact that c
contains its own address; that doesn't imply that c and &c are the
same value. I should have tried my own code before posting it.

"puts((char*)&c );" is correct (or as correct as anything can be in a
silly program like this one). "puts(c);" is wrong; it attempts to
dereference a garbage pointer.

--
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.
Nov 15 '05 #27
Joe Wright wrote:

Keith Thompson wrote:
"Old Wolf" <ol*****@inspir e.net.nz> writes:
Old Wolf wrote: char *c;
c is neither an array nor a pointer.


c is a pointer to char.

--
pete
Nov 15 '05 #28
pete wrote:

Joe Wright wrote:

Keith Thompson wrote:
"Old Wolf" <ol*****@inspir e.net.nz> writes:

>Old Wolf wrote: char *c;

c is neither an array nor a pointer.


c is a pointer to char.


.... with indeterminate value,

OK

--
pete
Nov 15 '05 #29
Le 01-10-2005, grid <pr******@gmail .com> a écrit*:
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;
}


As other have sayed, the two problems are the conversion
(char**) -> (char*) and the sizeof(char*).

Here is a well defined program:

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

int main(){
void* p= &p;
if ( strlen("abc") < sizeof(p) ){
memcpy(p, "abc", strlen("abc")+1 );
puts( (char*) p );
} else {
puts("Pointers too small");
}
return 0;
}

Marc Boyer
Nov 15 '05 #30

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

Similar topics

2
2933
by: Joona I Palaste | last post by:
AFAIK the C standard divides behaviour of different things into four classes. 1) Defined behaviour. The implementation must do exactly what the standard says. 2) Implementation-defined behaviour. The implementation must choose some behaviour, document it, and be consistent about it. 3) Unspecified behaviour. The implementation must pick one of several possible behaviours, but does not need to be consistent about it. 4) Undefined...
29
2273
by: Enrico `Trippo' Porreca | last post by:
Both K&R book and Steve Summit's tutorial define a getline() function correctly testing the return value of getchar() against EOF. I know that getchar() returns EOF or the character value cast to unsigned char. Since char may be signed (and if so, the return value of getchar() would be outside its range), doesn't the commented line in the following code produce implementation-defined behaviour?
13
2146
by: Chris Croughton | last post by:
Is the following code standard-compliant, and if so what should it do? And where in the standard defines the behaviour? #include <stdio.h> #define DEF defined XXX int main(void) { int defined = 2;
31
2678
by: DeltaOne | last post by:
#include<stdio.h> typedef struct test{ int i; int j; }test; main(){ test var; var.i=10; var.j=20;
8
5677
by: wkaras | last post by:
In my compiler, the following code generates an error: union U { int i; double d; }; U u; int *ip = &u.i; U *up = static_cast<U *>(ip); // error I have to change the cast to reinterpret_cast for the code
9
1811
by: horizon5 | last post by:
Hi, my collegues and I recently held a coding style review. All of the code we produced is used in house on a commerical project. One of the minor issues I raised was the common idiom of specifing: <pre> if len(x) 0: do_something() </pre>
26
2217
by: Frederick Gotham | last post by:
I have a general idea of the different kinds of behaviour described by the C Standard, such as: (1) Well-defined behaviour: int a = 2, b = 3; int c = a + b; (Jist: The code will work perfectly.)
285
9115
by: Sheth Raxit | last post by:
Machine 1 : bash-3.00$ uname -a SunOS <hostname5.10 Generic_118822-30 sun4u sparc SUNW,Sun-Fire-280R bash-3.00$ gcc -v Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/ specs gcc version 2.95.3 20010315 (release)
30
1774
by: Ioannis Vranos | last post by:
AFAIK the following is implementation-defined behaviour, am I right?: #include <stdio.h> int main(void) { int n= 0;
173
14091
by: Ron Ford | last post by:
I'm looking for a freeware c99 compiler for windows. I had intended to use MS's Visual C++ Express and use its C capability. In the past with my MS products, I've simply needed to make .c the filetype to invoke the C compiler. Here's a link http://www.microsoft.com/express/download/#webInstall The download is 2.6 megs, which is near a reasonable size for a compiler, but then setup.exe wants to download 87 megs of dot net framework...
0
11531
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
11120
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
11298
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 most users, this new feature is actually very convenient. If you want to control the update process,...
0
7390
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 into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
6087
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
6305
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4909
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
2
4510
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3511
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 effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.