puzzling error

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

I am not quite sure what is going on here but this is my tested and
compiled code. As written below at compile time I get this warning.

p.c: In function `main':
p.c:9: warning: assignment makes pointer from integer without a cast

I don't see the int in this code.

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

int main(void)
{
char p[] = "hello to all";
char *a;
printf("%s\n", p);
printf("%s\n", a = strfry(p)); //error on this line.
return 0;
}

strfry() is a GNU extension. It takes a char* as is sole argument and
returns a char*. Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

Bill
 
B

Ben Bacarisse

Bill Cunningham said:
I am not quite sure what is going on here but this is my tested and
compiled code. As written below at compile time I get this warning.

p.c: In function `main':
p.c:9: warning: assignment makes pointer from integer without a cast

I don't see the int in this code.

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

int main(void)
{
char p[] = "hello to all";
char *a;
printf("%s\n", p);
printf("%s\n", a = strfry(p)); //error on this line.
return 0;
}

strfry() is a GNU extension. It takes a char* as is sole argument and
returns a char*.

An undeclared function is assumed to return int. string.h is not
declaring strfry so the compiler assumes it returns an it and complains
when you assign the result to a char * variable.

The man page (or some other documentation) should tell you how to get
strfry declared properly. Adding -D_GNU_SOURCE to the compile line
works for me.
Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

p then points to the string rather than being an array initialised by
it. The content of strings can't be modified, so passing p to any
function that tried to alter its contents gives rise to undefined
behaviour. A segmentation fault is a Good Result for undefined
behaviour.
 
I

Ike Naar

I am not quite sure what is going on here but this is my tested and
compiled code. As written below at compile time I get this warning.

p.c: In function `main':
p.c:9: warning: assignment makes pointer from integer without a cast

I don't see the int in this code.

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

int main(void)
{
char p[] = "hello to all";
char *a;
printf("%s\n", p);
printf("%s\n", a = strfry(p)); //error on this line.
return 0;
}

strfry() is a GNU extension. It takes a char* as is sole argument and
returns a char*. Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

Apparently not all versions of the GNU toolset provide the strfry() function.
If the function is not provided, the strfry(p) call in your program is
a call to an undefined function, and the compiler will assume int for the
return type. You then assign the (presumably int) returnvalue to char *a,
hence the warning about the pointer-from-integer conversion.
 
M

Marc Boyer

Le 05-05-2011 said:
p.c: In function `main':
p.c:9: warning: assignment makes pointer from integer without a cast

I don't see the int in this code.

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

int main(void)
{
char p[] = "hello to all";
char *a;
printf("%s\n", p);
printf("%s\n", a = strfry(p)); //error on this line.
return 0;
}

strfry() is a GNU extension. It takes a char* as is sole argument and
returns a char*.

When I compile, I get also warning
warning: implicit declaration of function ‘strfry’
and when I read the man page, I see that you need to
define macro _GNU_SOURCE to use this function.

So, without _GNU_SOURCE, the function strfry is assumed
to return an int, and the expression
a = strfry(p)
puts an int into a char*.
Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

Because
char * p = "hello to all";
defines a pointer p on a *read only* string "hello to all",
and strfry tries to write into a read-only memory?

Marc Boyer
 
A

August Karlstrom

I am not quite sure what is going on here but this is my tested and
compiled code. As written below at compile time I get this warning.

p.c: In function `main':
p.c:9: warning: assignment makes pointer from integer without a cast

I don't see the int in this code.

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

int main(void)
{
char p[] = "hello to all";
char *a;
printf("%s\n", p);
printf("%s\n", a = strfry(p)); //error on this line.
return 0;
}

strfry() is a GNU extension. It takes a char* as is sole argument and
returns a char*. Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

The clang compiler will give you a bit more information (even without
warnings enabled):

$ clang test.c
test.c:9:24: warning: implicit declaration of function 'strfry' is
invalid in
C99 [-Wimplicit-function-declaration]
printf("%s\n", a = strfry(p)); //error on this line.
^
test.c:9:22: warning: incompatible integer to pointer conversion
assigning to
'char *' from 'int'
printf("%s\n", a = strfry(p)); //error on this line.
^ ~~~~~~~~~
2 warnings generated.


/August
 
O

osmium

Bill Cunningham said:
I am not quite sure what is going on here but this is my tested and
compiled code. As written below at compile time I get this warning.

p.c: In function `main':
p.c:9: warning: assignment makes pointer from integer without a cast

I don't see the int in this code.

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

int main(void)
{
char p[] = "hello to all";
char *a;
printf("%s\n", p);
printf("%s\n", a = strfry(p)); //error on this line.
return 0;
}

strfry() is a GNU extension. It takes a char* as is sole argument and
returns a char*. Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

Do you think you have now mastered C and want to take on Unix as a
challenge? Or what?

This is the wrong newsgroup for Unix based questions.
 
A

Angel

strfry() is a GNU extension. It takes a char* as is sole argument and
returns a char*. Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

RTFM, RTFF.
 
B

Bill Cunningham

osmium said:
Do you think you have now mastered C and want to take on Unix as a
challenge? Or what?

This is the wrong newsgroup for Unix based questions.

This is a GNU function. GNUs Not Unix.

Bill
 
B

Bill Cunningham

Ike said:
Apparently not all versions of the GNU toolset provide the strfry()
function. If the function is not provided, the strfry(p) call in your
program is
a call to an undefined function, and the compiler will assume int for
the return type. You then assign the (presumably int) returnvalue to
char *a, hence the warning about the pointer-from-integer conversion.

Ok but my implementation does support strfry and it does compile and
work. I just get that warning so the compiler must be smart enough to get it
right in the end.

Bill
 
K

Keith Thompson

Ben Bacarisse said:
Bill Cunningham said:
I am not quite sure what is going on here but this is my tested and
compiled code. As written below at compile time I get this warning.

p.c: In function `main':
p.c:9: warning: assignment makes pointer from integer without a cast

I don't see the int in this code.

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

int main(void)
{
char p[] = "hello to all";
char *a;
printf("%s\n", p);
printf("%s\n", a = strfry(p)); //error on this line.
return 0;
}

strfry() is a GNU extension. It takes a char* as is sole argument and
returns a char*.

An undeclared function is assumed to return int.

In C90. C99, dropped implicit int, so attempting to call an undeclared
function is a constraint violation.

"gcc -std=c99" gives:
c.c: In function 'main':
c.c:9:5: warning: implicit declaration of function 'strfry'
c.c:9:22: warning: assignment makes pointer from integer without a cast

(Yes, it's still following the C90 implicit int rule, but that's ok as
long as it always warns about constraint violations.)
string.h is not
declaring strfry so the compiler assumes it returns an it and complains
when you assign the result to a char * variable.
Right.

The man page (or some other documentation) should tell you how to get
strfry declared properly. Adding -D_GNU_SOURCE to the compile line
works for me.

In fact, the man page says:

#define _GNU_SOURCE
#include <string.h>

char *strfry(char *string);

where "#define _GNU_SOURCE" in the source is equivalent to
"-D_GNU_SOURCE" on the command line.

*Never* use a function you're not completely familiar with without
first reading the documentation.
Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

p then points to the string rather than being an array initialised by
it. The content of strings can't be modified, so passing p to any
function that tried to alter its contents gives rise to undefined
behaviour. A segmentation fault is a Good Result for undefined
behaviour.

Correction: the contents of string *literals* can't be modified.

More precisely, the contents of the array (which exists at run
time) which is associated with a string literal (which exists
only in your program source file) can't be modified. Even more
precisely, "can't be modified" means that attempting to modify them
is undefined behavior; an implementation could permit modifications,
but it wouldn't be doing you any favors.

This is an odd corner case. It would have made more sense for
string literals to be "const", so the compiler would (usually)
warn you about attempts to modify them, but that would have broken
a lot of pre-ANSI C code. C++, with less concern about backward
compatibility, does make string literals "const".
 
B

Bill Cunningham

osmium said:
Do you think you have now mastered C and want to take on Unix as a
challenge? Or what?

This is the wrong newsgroup for Unix based questions.

My we *must* have something to complain about. I have my POSIX interests
but I'll leave that for comp.unix.programmer.

Bill
 
K

Keith Thompson

Ike Naar said:
strfry() is a GNU extension. It takes a char* as is sole argument and
returns a char*. Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

Apparently not all versions of the GNU toolset provide the strfry() function.
If the function is not provided, the strfry(p) call in your program is
a call to an undefined function, and the compiler will assume int for the
return type. You then assign the (presumably int) returnvalue to char *a,
hence the warning about the pointer-from-integer conversion.

strfry() is part of the GNU C library (distinct from gcc).
It presumably does exist in Bill's implementation; he just didn't
invoke the compiler in the right way to make it visible
 
B

Bill Cunningham

Ben said:
Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

p then points to the string rather than being an array initialised by
it. The content of strings can't be modified, so passing p to any
function that tried to alter its contents gives rise to undefined
behaviour. A segmentation fault is a Good Result for undefined
behaviour.

Now I do believe I have learn something today. I have always thought of
char p[] and a char *p to be the same.

Bill
 
K

Keith Thompson

osmium said:
strfry() is a GNU extension. It takes a char* as is sole argument and
returns a char*. Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

Do you think you have now mastered C and want to take on Unix as a
challenge? Or what?

This is the wrong newsgroup for Unix based questions.

strfry is not a Unix function; it's unique to the GNU C library (and
remember, GNU stands for "GNU's Not Unix").

strfry() is GNU-specific, but the issue isn't; you'd have the same
problem with any non-standard function.
 
A

Angel

I don't know what RTFF means.

Same as RTFM, but s/Manual/FAQ/

Really, the man page of strfry() tells you exactly how to use it, but
you still screwed it up, and the comp.lang.c FAQ tells exactly what the
difference is between p[] = "abc"; and *p = "abc";. (Hint: The first one
is an array, the second a pointer.)

It's polite to check the documentation for an answer first before asking
your question here. Avoids making you look stupid as well. I'm fairly new
in this group, but I couldn't help notice some of the regulars being annoyed
with you, and I'm starting to see why.
 
A

Angel

Ok but my implementation does support strfry and it does compile and
work. I just get that warning so the compiler must be smart enough to get it
right in the end.

Warnings are there to tell you that something is wrong. Especially when
you are still learning the language, you should compile with "-pedantic
-Wall -Werror". Saves you a lot of frustration and embarrasment.
 
K

Keith Thompson

Bill Cunningham said:
Ben said:
Bill Cunningham said:
Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

p then points to the string rather than being an array initialised by
it. The content of strings can't be modified, so passing p to any
function that tried to alter its contents gives rise to undefined
behaviour. A segmentation fault is a Good Result for undefined
behaviour.

Now I do believe I have learn something today. I have always thought of
char p[] and a char *p to be the same.

And that's just one example of why, I suggest, C is the wrong
language for you.

Changing "char p[]" to "char *p" radically changes the meaning of
the declaration -- but the rules of C are such that your program
compiles without apparent error either way. Successful C programming
requires that you maintain a mental model of what's happening inside
your program -- not on the level of the hardware or machine code,
but in the C abstract machine.

char p[] = "some string";

makes p an array whose contents you're not permitted to modify.
In most but not all contexts, the name p "decays" to a pointer to
the first element of that array. The compiler won't tell you any of
this; you have to understand the language well enough to *know* it.

You have enough trouble getting your code to compile without
warnings and error messages, and you have the greatest difficulty
understanding what the messages mean and how to fix the problems
they're telling you about. But getting a clean compilation is the
*easy* part. There are a plethora of things you can do wrong in C
that the compiler won't complain about, with results ranging from
the program quietly *seeming* to work, to subtly incorrect output,
to outright crashes.

Not all languages are like that. I suggested Python; maybe it
isn't the best choice for you, but it's at a much higher semantic
level than C, and doesn't exhibit nearly as much undefined behavior.
Or pick some other higher-level language. It's certainly possible
to make subtle errors in any language. Languages other than C have
less tendency to sit back quietly and let you make them.
 
B

Bill Cunningham

Angel said:
Same as RTFM, but s/Manual/FAQ/

Really, the man page of strfry() tells you exactly how to use it, but
you still screwed it up, and the comp.lang.c FAQ tells exactly what
the difference is between p[] = "abc"; and *p = "abc";. (Hint: The
first one
is an array, the second a pointer.)

It's polite to check the documentation for an answer first before
asking your question here. Avoids making you look stupid as well. I'm
fairly new in this group, but I couldn't help notice some of the
regulars being annoyed with you, and I'm starting to see why.

Well I don't know about the FAQ but before I posted I read and re-read
man pages so before you accuse me of not doing it I did it and saw nothing
about defining any macro.
New to clc. clc is a pretty dramatic group and someone has to be picked
on. But I'm a big boy and when I have a problem I'll post. Of course I'll be
accused of al kinds of shit but I don't care. There is a killfile. But
that's too simple.

Bill
 
B

Bill Cunningham

Keith said:
Ben Bacarisse said:
Bill Cunningham said:
I am not quite sure what is going on here but this is my tested
and compiled code. As written below at compile time I get this
warning.

p.c: In function `main':
p.c:9: warning: assignment makes pointer from integer without a cast

I don't see the int in this code.

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

int main(void)
{
char p[] = "hello to all";
char *a;
printf("%s\n", p);
printf("%s\n", a = strfry(p)); //error on this line.
return 0;
}

strfry() is a GNU extension. It takes a char* as is sole argument
and returns a char*.

An undeclared function is assumed to return int.

In C90. C99, dropped implicit int, so attempting to call an
undeclared function is a constraint violation.

"gcc -std=c99" gives:
c.c: In function 'main':
c.c:9:5: warning: implicit declaration of function 'strfry'
c.c:9:22: warning: assignment makes pointer from integer without a
cast

(Yes, it's still following the C90 implicit int rule, but that's ok as
long as it always warns about constraint violations.)
string.h is not
declaring strfry so the compiler assumes it returns an it and
complains when you assign the result to a char * variable.
Right.

The man page (or some other documentation) should tell you how to get
strfry declared properly. Adding -D_GNU_SOURCE to the compile line
works for me.

In fact, the man page says:

#define _GNU_SOURCE
#include <string.h>

char *strfry(char *string);

where "#define _GNU_SOURCE" in the source is equivalent to
"-D_GNU_SOURCE" on the command line.

*Never* use a function you're not completely familiar with without
first reading the documentation.
Now if I change that char p[] to a char *p I get a
segmentation fault. What's up with that?

p then points to the string rather than being an array initialised by
it. The content of strings can't be modified, so passing p to any
function that tried to alter its contents gives rise to undefined
behaviour. A segmentation fault is a Good Result for undefined
behaviour.

Correction: the contents of string *literals* can't be modified.

More precisely, the contents of the array (which exists at run
time) which is associated with a string literal (which exists
only in your program source file) can't be modified. Even more
precisely, "can't be modified" means that attempting to modify them
is undefined behavior; an implementation could permit modifications,
but it wouldn't be doing you any favors.

This is an odd corner case. It would have made more sense for
string literals to be "const", so the compiler would (usually)
warn you about attempts to modify them, but that would have broken
a lot of pre-ANSI C code. C++, with less concern about backward
compatibility, does make string literals "const".

My man page mentions nothing about a _GNU_SOURCE or I would have defined
it in the source code rather than at compile time. I don't suppose it would
matter though as long as the preprocessor sees it.

Bill
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top