puzzling error

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

Marc said:
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.

My man page does say this. It doesn't mention defining any macro. Man
pages aren't the same. Try this link and you'll see what I mean.

http://linux.die.net/man/3/strfry
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
 
B

Bill Cunningham

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

Some people Keith *must pick* and find *something* wrong.

Bill
 
B

Bill Cunningham

Bill said:
My man page does say this. It doesn't mention defining any macro.
Man pages aren't the same. Try this link and you'll see what I mean.

http://linux.die.net/man/3/strfry

Pardon me Marc. I do see now the little define above the include
directive. I must've overlooked it when looking at my man pages. Sorry I
missed it. I am not used to looking for such things so my bad. Atleast my
code compiled and I have learned something today.

Bill
 
B

Bill Cunningham

Bill said:
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.

Ok I see it now. I'm not used to looking for defines. I will keep a look
out now. Sorry my bad.

Bill
 
B

Bill Cunningham

Marc said:
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?

The page link I mailed you earlier had the define of _GNU_SOURCE. My man
page makes no mention of this macro on my linux machine. This macro is
needed though I can see so I tried #define _GNU_SOURCE in the source file
and got the same warning. I removed that and at compile time
used -D_GNU_SOURCE and got a clean install. Do you know the difference
between these two different kinds of defines?
I don't have much experience with non standard functions so my knowledge
is very limited. But if I didn't look on line or learn about this macro from
clc I would still be getting this warning.

Bill
 
B

Bill Cunningham

Bill said:
Ok I see it now. I'm not used to looking for defines. I will keep
a look out now. Sorry my bad.

But it's still not mentioned on the man page on my machine. But it
mentioned on the online man page.

B
 
B

Bill Cunningham

Keith said:
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.

Yes these little things like the syntax of the language is tricky. I
understand using functions and have the most experience with the c90 ones.
Types such as uint32_t (if that's right) are sounding more interesting now
though.
But I have looked at perl and c++. These two might be interesting. But
studying sockets as I was I was learning how to code if not the subtleness
of C's syntax. This macro mentioned by others was no where in my man pages
but it is in the online man pages. Speaking of C++ it seems like a more
complicated C.

Bill
 
B

Bill Cunningham

Ben said:
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.

Ben my man page says nothing about _GNU_SOURCE. the online man page does
but not mine. What's the difference in defining at compile and putting

#define _GNU_SOURCE
in the source file. The above doesn't work for me.

Bill
 
O

osmium

Kenneth Brody said:
How is it that someone with the subtle knowledge of "GNU's Not Unix" is
unable to comprehend such basic C concepts after all these years?

Perhaps that's why bumper stickers are so popular? Short, pithy things
stick. The other answers indicate Bill is, indeed, a troll, as many say.
 
B

Bill Cunningham

Kenneth said:
They are similar in many ways, depending on where it's used.

With both versions, an unadorned reference to "p" gives you a pointer
to the first char in the array/buffer.

When declaring a function parameter, they are pretty much
interchangeable:
char *mystrfunc(char *p);
and
char *mystrfunc(char p[]);

are, for all intents and purposes, equivalent[1].

However, when declaring a variable, such as what you have done, there
is a critical difference between:

char p[] = "foobar";
and
char *p = "foobar";

The difference being that the former version creates the array and
calls it "p", whereas the latter version stores a string literal in
unmodifiable memory, and then creates a pointer (called "p") which
points to it. Again, in many cases, the difference is irrelevant.

However, the fact that the latter version points "p" to _unmodifiable_
_memory_ is critical if your code attempts to modify the contents of
that buffer. (The pointer "p" itself is, of course, modifiable.)

There is, of course, also a world of difference between "extern"
declarations, such as:

extern char p[];
and
extern char *p;


[1] I was going to say that, if you declare a parameter as "char
p[]", then you can't do things like "p++". However, my compiler,
even with warnings at max, allows it. I don't know if this is an
extension, or something that the Standard allows.

I think I might be a little confused because these are the same:

char **argv and char *argv[].

B
 
B

Bill Cunningham

Kenneth said:
How is it that someone with the subtle knowledge of "GNU's Not Unix"
is unable to comprehend such basic C concepts after all these years?

Sometimes I think I am a little underestimated. I get excited and post
too soon sometimes. It's also hard for me to communicate. Try holding a
conversation with me I would probably have to ask you what we were just
talking about.

Bill
 
B

Bill Cunningham

Kenneth said:
On gcc (and many other compilers, though the Standard is mute on the
subject of command line flags to a compiler), the "-D_GNU_SOURCE"
flag on the command line is equivalent of putting this at the top of
the source file:
#define _GNU_SOURCE

You say you tried the #define in the source file. Did you put it
above the #include <string.h> line? These two versions are _not_
equivalent:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
and
#include <stdio.h>
#include <string.h>
#define _GNU_SOURCE

No I put the define in the middle of the two include directives.

Bill
 
K

Keith Thompson

Kenneth Brody said:
On 5/5/2011 12:11 PM, Bill Cunningham wrote: [...]
Now I do believe I have learn something today. I have always thought of
char p[] and a char *p to be the same.

They are similar in many ways, depending on where it's used.

With both versions, an unadorned reference to "p" gives you a pointer to the
first char in the array/buffer.

When declaring a function parameter, they are pretty much interchangeable:

char *mystrfunc(char *p);
and
char *mystrfunc(char p[]);

are, for all intents and purposes, equivalent[1].

They're *exactly* the same.

[...]
[1] I was going to say that, if you declare a parameter as "char p[]", then
you can't do things like "p++". However, my compiler, even with warnings at
max, allows it. I don't know if this is an extension, or something that the
Standard allows.

It's 100% standard; the parameter declaration "char p[]" is adjusted at
compile time to "char *p". See C99 6.7.5.3p7.

Section 6 of the comp.lang.c FAQ, <http://www.c-faq.com/>, explains all
this very well.
 
C

Chad

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.

Python is pretty easy to learn. So is Visual Basic. I figure pretty
much anyone can learn it in a reasonable amount of time since both
programming languages seem to be popular among the 15 - 17 yr old
script kiddie groups on sites like Yahoo Checkers.
 
K

Keith Thompson

Kenneth Brody said:
Note that my ISP's Linux box (I have shell access) does not mention
_GNU_SOURCE on strfry's man page. Yet, it does require the definition:
[...]

That's suprising. On one of the systems I use, the man page does
specify #define _GNU_SOURCE, and it's dated 1993-04-12. (It's a CentOS
5.6 system).
 
B

Bill Cunningham

Oh and btw I am using OE quotefix all the time now. I've really gotten
used to it and it makes posting much easier to understand.

Bill
 
A

Angel

Kenneth Brody said:
Note that my ISP's Linux box (I have shell access) does not mention
_GNU_SOURCE on strfry's man page. Yet, it does require the definition:
[...]

That's suprising. On one of the systems I use, the man page does
specify #define _GNU_SOURCE, and it's dated 1993-04-12. (It's a CentOS
5.6 system).

I've checked the man pages of several glibc-based systems and they all
mention the #define.
 
B

Ben Bacarisse

Keith Thompson said:
Ben Bacarisse <[email protected]> writes:

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

Ah, that was a typo. I intended to write "the content of *such* strings
can't be modified" because I did not want to write what you've just
written (string literals are lexical constructs and I don't like
talking about them as if they exist at run time) and I did not want to
write what you go on to write:
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.

I though that just saying that strings such as those pointed to by p
can't be modified was the right level of detail, but I missed a crucial
word.

<snip>
 
B

Ben Bacarisse

Bill Cunningham said:
#define _GNU_SOURCE
in the source file. The above doesn't work for me.

If you want to find out why, ask in comp.unix.programmer. The answer
is likely to be highly system specific and is not really a C question.
 

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
474,085
Messages
2,570,597
Members
47,220
Latest member
AugustinaJ

Latest Threads

Top