0

My question is, if it is correct to define both:

typedef void* Elem;
typedef const void* const constElem; 

If I know that I would work with const and non const generic elements, for example for the copyElem function as a parameter, I would prefer to get it as const, for the const correctness, is this practical?

pfnuesel
  • 14,093
  • 14
  • 58
  • 71
KittyT2016
  • 195
  • 9
  • 3
    Using a typedef for either of these is (IMO) impractical. – William Pursell Jan 29 '16 at 16:55
  • I think you only want the first `const` in the `constElem` definition. The second `const` is specifying that a variable of type `constElem` is constant and thus can not be changed. I think you meant is that only what a `constElem` _points_ to can not be changed. – pcarter Jan 29 '16 at 16:56
  • 1
    pcarter, actually yes, but the first const doesn't bother's anyway, isn't it ? For example for a copy function of Elem, no reason to change the pointer eather, as what it points to. – KittyT2016 Jan 29 '16 at 17:00
  • Generally you will want to avoid typedef'd pointers. They usually only serve to obscure the level of pointer indirection and make your code less readable (not to mention much more difficult to debug). – David C. Rankin Jan 29 '16 at 17:26

2 Answers2

1

const void *const doesn't buy you much, unless it is used as the type of a function parameter:

void foo(const void *const e)
{
    e = NULL; // compile-time error because of the second const
    char *s = e; // compile-time error because of the first const
    const char *t = e; // OK
}
...
char x[] = "test";
foo(x); // you can be confident that foo will not modify the contents

For regular usage it is impractical because the first const says that the dereferenced value cannot be modified, but void pointers cannot be dereferenced anyway. The second const essentially doesn't allow you to reassign the pointer once it is initialised.

Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
1

I don't see how there is a matter of correctness here, except inasmuch as yes, both typedefs you present are syntactically correct, and it is possible that a program would have use for both types.

As a matter of style, however, it is poor form to hide pointer nature behind a typedef. It very easily becomes confusing.

It is also a bit questionable to typedef anything as void * -- it provides no type safety of any significance, and not much semantic assistance either. If you really want to accept a pointer to anything, then just say void *. If, on the other hand, you want to hide the details of a struct type, then just declare the structure type as an incomplete type, and leave it that way:

struct Elem;

Optionally, typedef that for convenience:

typedef struct Elem Elem;

Personally, and again as a matter of style, I would prefer to see the const keyword than to see a typedef that rolls in the const, no matter how clearly designated.

Note also that all questions of style aside, this particular typedef ...

typedef const void* const constElem;

... seems of rather narrow usefulness. It designates a pointer whose value cannot be changed and that points to an object that also cannot be changed. A non-const pointer to a const object is much more often what you want. Note, too, that the uncertainty over what constElem should mean is one consequence of rolling up pointer nature inside the Elem typedef.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157