Re: L in return



On Thu, 19 Nov 2009 13:08:33 -0800, Keith Thompson wrote:

[snipped and re-ordered for thematic reasons]
Passing a pointer-to-(non-const)-char to a function that takes a
pointer-to-const-char, as in "const_func(arg);" above, is perfectly
valid. The "const" on the parameter declaration is a promise not to use
the parameter to modify what the parameter points to. The code doesn't
try to violate that promise, so there's no problem.

Passing a pointer-to-const to a function that takes a
pointer-to-non-const, on the other hand, is a constraint violation. The
declaration "const char *const_arg;" promises not to use const_arg to
modify the data it points to. You can't pass that pointer to a function
that doesn't make a similar promise. But as we can see, you can modify
the same data through another path.

The above program should compile and run without error. If you change
"#if 0" to "#if 1", the compiler will complain.

I'm just about there with this material and this is certainly good source
to get right at the meat of it. This shows when the #ifs are changed:

dan@dan-desktop:~/source$ gcc -std=c99 -Wall -Wextra hi3.c -o out
hi3.c: In function ‘const_func’:
hi3.c:13: error: assignment of read-only location ‘*param’
dan@dan-desktop:~/source$ cat hi3.c

#include <stdio.h>

void func(char *param)
{
*param = 'H';
puts(param);
}

void const_func(const char *param)
{
#if 1
*param = 'H'; /* illegal, violates "const" promise */
#endif
puts(param);
}

int main(void)
{
char s[] = "hello, world";
char *arg = s;
const char *const_arg = s;

func(arg); /* ok */
#if 0
func(const_arg); /* illegal, violates promise made by */
/* declaration of const_arg */
#endif
const_func(arg); /* ok, doesn't violate any "const" promise */
const_func(const_arg); /* ok */
return 0;
}

// gcc -std=c99 -Wall -Wextra hi3.c -o out
dan@dan-desktop:~/source$ gcc -std=c99 -Wall -Wextra hi3.c -o out
hi3.c: In function ‘main’:
hi3.c:26: warning: passing argument 1 of ‘func’ discards qualifiers from
pointer target type
dan@dan-desktop:~/source$ cat hi3.c

#include <stdio.h>

void func(char *param)
{
*param = 'H';
puts(param);
}

void const_func(const char *param)
{
#if 0
*param = 'H'; /* illegal, violates "const" promise */
#endif
puts(param);
}

int main(void)
{
char s[] = "hello, world";
char *arg = s;
const char *const_arg = s;

func(arg); /* ok */
#if 1
func(const_arg); /* illegal, violates promise made by */
/* declaration of const_arg */
#endif
const_func(arg); /* ok, doesn't violate any "const" promise */
const_func(const_arg); /* ok */
return 0;
}

// gcc -std=c99 -Wall -Wextra hi3.c -o out

Let's look at a (perhaps) simpler example.

#include <stdio.h>

void func(char *param)
{
*param = 'H';
puts(param);
}

Why don't we see an H in stdout here?

dan@dan-desktop:~/source$ gcc -std=c99 -Wall -Wextra hi4.c -o out
dan@dan-desktop:~/source$ ./out
here in func

Hello, world
Hello, world
Hello, world
dan@dan-desktop:~/source$ cat hi4.c

#include <stdio.h>

void func(char *param)
{
puts("here in func\n");
*param = 'H';
puts(param);
}

void const_func(const char *param)
{
#if 0
*param = 'H'; /* illegal, violates "const" promise */
#endif
puts(param);
}

int main(void)
{
char s[] = "hello, world";
char *arg = s;
const char *const_arg = s;

func(arg); /* ok */
#if 0
func(const_arg); /* illegal, violates promise made by */
/* declaration of const_arg */
#endif
const_func(arg); /* ok, doesn't violate any "const" promise */
const_func(const_arg); /* ok */
return 0;
}

// gcc -std=c99 -Wall -Wextra hi4.c -o out
dan@dan-desktop:~/source$

--
frank

"Guns: yes, they are harmful."
.



Relevant Pages