is this intentional?

A

aegis

typedef struct foo *FOO;

struct foo {
int a;
};

void func(const FOO baz);

int main(void)
{
struct foo baz;
func(&baz);
return 0;
}

void func(const FOO baz)
{
static struct foo test;
baz = &test;
return ;
}


this treats "baz" as a const pointer
to struct foo and not a pointer to struct foo
qualified by const. if FOO was really a synonym
for struct foo, it would not do this.

what part of the standard describes this behavior
if it isn't a bug in my compiler?
 
P

pete

aegis said:
typedef struct foo *FOO;

struct foo {
int a;
};

void func(const FOO baz);

int main(void)
{
struct foo baz;
func(&baz);
return 0;
}

void func(const FOO baz)
{
static struct foo test;
baz = &test;
return ;
}

this treats "baz" as a const pointer
to struct foo and not a pointer to struct foo
qualified by const. if FOO was really a synonym
for struct foo, it would not do this.

If FOO was really a synonym for struct foo,
then your code would look like this:

typedef struct foo FOO;
void func(const FOO *baz);
 
A

aegis

pete said:
If FOO was really a synonym for struct foo,
then your code would look like this:

typedef struct foo FOO;
void func(const FOO *baz);

I of course meant

"if FOO was really a synonym for struct foo *, it would not do this"
my original question remains.
 
L

Lawrence Kirby

typedef struct foo *FOO;

struct foo {
int a;
};

void func(const FOO baz);

int main(void)
{
struct foo baz;
func(&baz);
return 0;
}

void func(const FOO baz)
{
static struct foo test;
baz = &test;
return ;
}


this treats "baz" as a const pointer
to struct foo and not a pointer to struct foo
qualified by const.

I don't see the distinction you are trying to make. If FOO is a pointer to
struct foo then const FOO is a const pointer to struct foo.
if FOO was really a synonym
for struct foo, it would not do this.

When you qualify a pointer type you qualify the pointer type itself, not
the type it is pointing at. I'm not clear why you think otherwise.
what part of the standard describes this behavior if it isn't a bug in
my compiler?

I C99 6.7.3 describes const.

Lawrence
 
M

Michael Mair

aegis said:
I of course meant

"if FOO was really a synonym for struct foo *, it would not do this"
my original question remains.

typedef does _not_ mean the same as #define.
With #define FOO struct foo *
"const FOO baz" would do what you expect.

typedef is _not_ a text replacement, so a pointer "type" generated
with typedef will become a const pointer if preceded by const.

This is one of the reasons why one should never use typedef to
generate a "type" which is a pointer to something.

Why do I write "type": Because new types are made using struct.


Cheers
Michael
 
R

Richard Kettlewell

aegis said:
"if FOO was really a synonym for struct foo *, it would not do this"
my original question remains.

Given the original typedef declaration, FOO denotes the same type as
struct foo *; it is not a synonym for the string 'struct foo *'.
Section 6.7.7.

When you write 'const FOO baz', the compiler promises that baz has
type FOO and is const. i.e. that baz is a pointer and is const.
Section 6.7.5.
 
A

alexmdac

In your code the pointer's constant, but the thing it points to isn't
constant. If the pointee is to be constant, the const keyword should
be after the star.

const int *pn; /* const pointer to an int */
int * const pn; /* pointer to a const int */
const int * const pn; /* const pointer to a const int */
 
M

Michael Mair

In your code the pointer's constant, but the thing it points to isn't
constant. If the pointee is to be constant, the const keyword should
be after the star.

Sorry, this is crap.
const int *pn; /* const pointer to an int */ pointer to const int
int * const pn; /* pointer to a const int */ const pointer to int
const int * const pn; /* const pointer to a const int */
correct

-Michael
 
J

Jonathan Burd

In your code the pointer's constant, but the thing it points to isn't
constant. If the pointee is to be constant, the const keyword should
be after the star.

const int *pn; /* const pointer to an int */
int * const pn; /* pointer to a const int */
const int * const pn; /* const pointer to a const int */

???

/* poof.c */
#include <stdio.h>

int
main (void)
{
const int *ptr_to_constn;
int a = 10;

#if 1
int b = 60;
int * const constp_to_n = &b;

/* error - assignment to read-only variable */
constp_to_n = &a;
#endif

ptr_to_constn = &a;
printf ("%p %d\n", (void*) ptr_to_constn, *ptr_to_constn);


#if 1
/* error - trying to modify read-only location. */
*ptr_to_constn = 1;
#endif

++ptr_to_constn; /* pointing to unknown stuff now */
printf ("%p %d\n", (void*) ptr_to_constn, *ptr_to_constn);
/* UB */

return 0;
}

Regards,
Jonathan.
 
A

alexmdac

Ok we've established I got the const stuff the wrong way round. You
can all stop being sarcastic at me now.
 
K

Keith Thompson

Ok we've established I got the const stuff the wrong way round. You
can all stop being sarcastic at me now.

You're missing the point. Nobody was giving you a hard time about the
const stuff, just pointing out your error. The sarcasm was triggered
by your failure to post properly.

Due to a bug in Google news, you're posting articles with no context,
which makes it difficult to understand what you're talking about.
Note, for example, that I've quoted what you wrote in this reply.

There happens to be an easy workaround, documented in CBFalconer's sig
quote:

"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
 
A

alexmdac

Keith said:
You're missing the point. Nobody was giving you a hard time about the
const stuff, just pointing out your error. The sarcasm was triggered
by your failure to post properly.
Just kidding :) Thanks for the heads-up.
 
C

CBFalconer

Ok we've established I got the const stuff the wrong way round.
You can all stop being sarcastic at me now.

What const stuff? Who is sarcastic. See sig below and quote.
 
M

Max T. Woodbury

CBFalconer said:
What const stuff? Who is sarcastic. See sig below and quote.

> --
> "If you want to post a followup via groups.google.com, don't use
> the broken "Reply" link at the bottom of the article. Click on
> "show options" at the top of the article, then click on the
> "Reply" at the bottom of the article headers." - Keith Thompson.

Hmm. On the reader I'm using in threaded mode his responses
were in context and quite economical. I can understand his
confusion. On the other hand Keith's point is also well taken
but I'm not sure he has diagnosed the problem correctly since
the threading does seem to be properly structured. This is
intended only as an observation, not as criticism.

max
 
K

Keith Thompson

Max T. Woodbury said:
Hmm. On the reader I'm using in threaded mode his responses
were in context and quite economical. I can understand his
confusion. On the other hand Keith's point is also well taken
but I'm not sure he has diagnosed the problem correctly since
the threading does seem to be properly structured. This is
intended only as an observation, not as criticism.

The problem isn't the threading (the References: header is ok). The
problem is that the "Reply" link at the bottom of the article doesn't
support quoting (it opens a tiny text entry box with nothing in it),
whereas the "Reply" link that only becomes visible when you click on
the "show options" link does (it opens a reasonably sized text entry
box with the previous article properly quoted with ">" prefixes).

If your newsreader lets you easily go to the parent article (mine
does), *and* if the parent article happens to be available on hour
server, this isn't as much of a problem, but it's still good to
provide some context in the followup itself (as you've done yourself,
Max).
 
P

pete

Michael Mair wrote:
This is one of the reasons why one should never use typedef to
generate a "type" which is a pointer to something.

I wouldn't say "never".
For these type array sorting functions,

void sort(e_type *array, size_t nmemb);

typedefing pointer types when sorting arrays of pointers,
is no different from typdefing any other element type.

/* BEGIN ptr_sort.c */
/*
** lencomp() compares pointers to strings,
** according to string length.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define STRUCTURES 0 /* Either 1 or 0 */

#define SORT_FUNCTIONS { \
no_sort, "This is the original order of the test array:",\
si_sort, "Stable insertionsort:", \
s8sort, "Nonstable Shellsort, four is after " \
"nine, and eight is before three:", \
/*
q_sort, "Standard library qsort, " \
"unspecified ordering of equal keys:", \
*/}
#define NUMBERS { \
{"one"},{ "two"},{"three"},{"four"},{"five"}, \
{"six"},{"seven"},{"eight"},{"nine"},{ "ten"}, \
}

#define GT(A, B) (lencomp((A), (B)) > 0)
#define NMEMB (sizeof numbers / sizeof *numbers)
#define SORTS (sizeof s_F / sizeof *s_F)
#define str(s) # s
#define xstr(s) str(s)

#if STRUCTURES != 0
#define E_TYPE \
struct node { \
void *data; \
struct node *next; \
}
#else
#define E_TYPE char *
#endif

typedef E_TYPE e_type;

int lencomp(const void *, const void *);
void no_sort(e_type *, size_t);
void si_sort(e_type *, size_t);
void s8sort(e_type *, size_t);
void q_sort(e_type *, size_t);

int main(void)
{
size_t element, sort;
struct sf {
void (*function)(e_type *, size_t);
const char *description;
} s_F[] = SORT_FUNCTIONS;
const e_type numbers[] = NUMBERS;
e_type copy[NMEMB];

puts("/* BEGIN output from ptr_sort.c */\n\nArrays of type "
xstr(E_TYPE) ",\nare being sorted by string length.");
for (sort = 0; sort != SORTS; ++sort) {
putchar('\n');
puts(s_F[sort].description);
memcpy(copy, numbers, sizeof copy);
s_F[sort].function(copy, NMEMB);
for (element = 0; element != NMEMB; ++element) {

#if STRUCTURES != 0
puts(copy[element].data);
#else
puts(copy[element]);
#endif

}
}
puts("\n/* END output from ptr_sort.c */");
return 0;
}

int lencomp(const void *a, const void *b)
{

#if STRUCTURES != 0
const size_t a_len = strlen((*(e_type*)a).data);
const size_t b_len = strlen((*(e_type*)b).data);
#else
const size_t a_len = strlen(*(e_type*)a);
const size_t b_len = strlen(*(e_type*)b);
#endif

return b_len > a_len ? -1 : a_len != b_len;
}

void no_sort(e_type *array, size_t nmemb)
{
array || nmemb;
}

void si_sort(e_type *array, size_t nmemb)
{
e_type temp, *base, *low, *high;

if (nmemb > 1) {
--nmemb;
base = array;
do {
low = array++;
if (GT(low, array)) {
high = array;
temp = *high;
do {
*high-- = *low;
if (low == base) {
break;
}
--low;
} while (GT(low, &temp));
*high = temp;
}
} while (--nmemb != 0);
}
}

void s8sort(e_type *array, size_t nmemb)
{
e_type temp, *i, *j, *k, *after;

after = array + nmemb;
if (nmemb > (size_t)-1 / 3) {
nmemb /= 3;
}
do {
for (i = array + nmemb; after != i; ++i) {
j = i - nmemb;
if (GT(j, i)) {
k = i;
temp = *k;
do {
*k = *j;
k = j;
if (nmemb + array > j) {
break;
}
j -= nmemb;
} while (GT(j, &temp));
*k = temp;
}
}
nmemb = nmemb != 2 ? 3 * nmemb / 8 : 1;
} while (nmemb != 0);
}

void q_sort(e_type *array, size_t nmemb)
{
qsort(array, nmemb, sizeof *array, lencomp);
}

/* END ptr_sort.c */
 
M

Michael Mair

pete said:
Michael Mair wrote:



I wouldn't say "never".
[snip: good counter-example]

Right, I should not have said "never", either.
s/never/nearly never/
I have done this in code of mine, too, until I realised that
most of the time I just wanted to get around typing the extra
'*' which is no good reason at all. I never fell into one of
the traps this lazy practice provides but nonetheless this is
one of the things where a couple of keystrokes more really
gives you a gain in program clarity and safety.
So my rule is "never" -- unless this is the obvious,
"necessary", simple and sort of best way of implementing
something.


Cheers :)
Michael
 

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,159
Messages
2,570,879
Members
47,416
Latest member
LionelQ387

Latest Threads

Top