3

I have a struct type_s. Then I typedef a pointer to a struct type_s as type.

If I have a const struct type_s* then the compiler will correctly complain if an assignment is made to the struct member, as seen in function Test1(). But if I make a const type, which is a typedef for the same struct pointer the compiler will not complain and compile, function Test2().

typedef struct type_s* type ;
struct type_s
{
    int a ;
} ;

void Test1( const struct type_s* t )
{
    t->a = 123 ;  //complains, ok
}

void Test2( const type t )
{
    t->a = 123 ;   //doesn't, it should in my oppinion
}

To me they are logically both the same thing. What am I missing?

Is the only solution to create another typedef for a constant pointer to that struct like this:

typedef const struct type_s* ctype ;

which will work correctly as in Test1().

this
  • 5,229
  • 1
  • 22
  • 51
  • 1
    If you have `const T t`, that means that `t` is the thing that's const. `typedef`s are not the same as `#define`s. – Oliver Charlesworth Apr 13 '14 at 14:35
  • Once you defined the type (with the `typedef`) you can't change that type any further. Any qualifiers apparently applied to the type, apply instead to the object. The `const` in question is not ignored; it is applied to the object `t`. Inside the function you can't do `t = NULL;` – pmg Apr 13 '14 at 14:39
  • 3
    `const type t` means `struct s_type * const t`. Yet another reason not to use pointer typedefs. – M.M Apr 13 '14 at 14:40
  • 1
    [C99 in HTML](http://port70.net/~nsz/c/c99/n1256.html) – pmg Apr 13 '14 at 14:42
  • @MattMcNabb I have the same opinion, but then I read a lot of c libraries where that is done constantly to hide the struct. – this Apr 13 '14 at 14:45
  • 1
    There's lots of bad code out there – M.M Apr 13 '14 at 14:52
  • @MattMcNabb I guess making someone write that extra `*` isn't so bad :), + you know what the type really is. – this Apr 13 '14 at 15:00

2 Answers2

2

What you're missing is that a const pointer is not the same thing as a pointer to a const object. You have one of each. A const pointer is a pointer whose stored address is not modifiable; a pointer to const is one which cannot be used to modify its referent.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Where do I have a *const pointer*? – this Apr 13 '14 at 14:38
  • 1
    `const type` is equivalent to `type const` which in your case gives you `struct type_s* const` whereas you thought you were getting `const struct type_s*`. Another way to look at it is that you wanted `(const struct type_s)*` but you got `const (struct type_s*)`. – John Zwinck Apr 13 '14 at 14:41
1

They are not the same thing. const has different semantics when applied to the definition or declaration of a pointer variable and a non-pointer variable.

const struct type_s *t 

The above statement defines t to be a pointer to an object of type const struct type_s. Here, const qualifies the type struct type_s of the object t points to, not the pointer t.

typedef struct type_s *type ;

The above statement defines an alias named type for the type struct type_s *.

const type t;
// equivalent to
type const t;
// equivalent to
struct type_s *const t;

The above statement defines t to be a constant object of type type. Here const qualifies the object. You cannot replace the typedef with its original type and reinterpret it as if it were a macro. The pointer information is embedded in the typedef and it will be treated as a non-pointer type.

ajay
  • 9,402
  • 8
  • 44
  • 71