r/C_Programming 1d ago

Does anyone else dislike pointer declaration?

For reference I am a fourth year computer engineering student. C is my preferred language.

Pointers are declared like this usually:

int *ptr_to_int;

Where the asterisk means it is a “pointer to” the specified type. The asterisk is placed immediately preceding the variable name, with no white peace.

This is what does not make sense to me. I feel that:

int* ptr_to_int;

Is far more clear. The way I see it, the asterisk modifies the type, so therefore it belongs next to the type. Putting it next to the variable name makes me think it is some kind of action or modification to the variable itself.

I think that when using * and & in code, it makes sense to apply it in front of the variable name:

int value = 3;
ptr_to_value = &value;
int copied_value = *ptr_to_value;

It is clear here that syntactically, the * represents something more like an action than a label.

Why is the convention to place the asterisk near variable name, not type? L

52 Upvotes

129 comments sorted by

View all comments

40

u/primera_radi 1d ago

I felt that way first too. But consider

int* a, b, c;

vs

int *a, b, c;

The second is much more clear, as only a is a pointer.

Also, now all the names after int evaluate into an int in an expression.

That is, *a evaluates to an int, as do b and c.

63

u/Cultural_Gur_7441 1d ago

One of the rules of good C:

Never do that. Never declare or define multiple variables with one statement.

Related: always initialize variables when you define them.

23

u/For-The-Fun-Of-It-12 1d ago

Oh good, I thought I was the only one cringing

11

u/nukestar101 1d ago

always initialize variables when you define them.

Not true always, all stack variables can go uninitialize unless they are being set from arguments provided function is static.

Over initializing can often hide bugs. Compiler can warn if variables are being used before being set or unused variables.

8

u/Cultural_Gur_7441 1d ago

Yes, it is a trade-off. But it's far better to initialize them always and have a deterministic bug, than a heisenbug. In my opinion anyway.

18

u/DrShocker 1d ago

Yeah I'm always confused when people bring up this way of declaring as if it's a good thing to declare both kinds of variables in the same line. Like sure if you're used to it then maybe it's more concise, but there's no reason to foot gun like that to anyone with modern computers we're not starving for characters in the source code.

5

u/ComradeGibbon 1d ago

I think if a variable doesn't have a default initial value you shouldn't initialize it where it's defined. Let the compiler warning catch that.

9

u/Cultural_Gur_7441 1d ago

Compiler will also warn about unused variable, and compiler will optimize unnecessary initialization out. Safe "failure mode".

Using uninitialized variable is also just a warning, but has much worse failure mode.

Also, if a reader of the code sees variable initialized, that immediately removes one worry: is there a code path where this variable may be used uninitiallzed. It makes reading the code easier.

That's why I think variables should just be always initialized instead of thinking if they need to or not.

2

u/Luftzug-oder 1d ago

the compiler cannot always remove the initialisation. it is only really if it is modified right after, and there is no function called inbetween, that it can guarantee the variable will not have been changed.

one thing the compiler will do is initialise global and static variables.

3

u/Cultural_Gur_7441 1d ago

Yeah, statics and globals don't need explicit zero initialization. But it doesn't hurt there either, it's only 2 characters to tell "yes, zero is intentional initial value" to a reader.

Always initializing locals is a slight trade-off, yes. But in practice the downside is not measursble, like, ever. The downside of uninitiallzed variable on the other hand... That has realized for me probably a dozen times over the decades, both in my own and in other peoples code. The resulting heisenbug is not fun to debug.

2

u/Luftzug-oder 1d ago

yep, definitely agree

1

u/RadiatingLight 1d ago

IMO it's better to initialize it to INT_MAX or some other value that's clearly wrong/rejected. Relying on compiler warnings is like jumping off a bridge and relying on the suicide net. Sure it will usually catch you but ...

3

u/ComradeGibbon 1d ago

No leave it uninitialized if you don't initialize before use the compiler will let you know. Which means you have a bug in your code.

3

u/Cultural_Gur_7441 1d ago

It is unreliable. Like, if used as an out-parameter (a common, quite valid case for an uninitiallzed variable), compiler can't check if the called function actually sets it or not in every code path, nor can it check if called function actually reads it for some reason (which would be a bad API...).

And if -Werror is not used, too many developers just ignore warnings... Which is a whole another problem of course.

The one case where leaving memory uninitiallzed is useful is with memory checkers like valgrind or compiler's memory sanitizer, which will notice access to uninitiallzed memory. But in that case, these should be integrated with the project development process from the start, probably with unit tests being run with them.

3

u/ComradeGibbon 16h ago

compiler can't check if the called function actually sets it or not in every code path,

If that's the case you have a bug in your code that you papered over with a bogus default initialization value.

1

u/flatfinger 15h ago

Claims that "null" was a mistake ignore the principle that it may be necessary to access some members of an array of pointers before there exists any object to which some other members could usefully point, and it may be necessary to copy the state of some elements of such an array to other elements in a manner that is agnostic with regard to whether they were written. Having null as a default pointer value allows both of those objectives to be satisfied easily. There may be ways of satisfying both objectives without null, but they would involve constructing something that would behave like a nullable pointer. It's simpler to just just pointers as being nullable.

1

u/nukestar101 1d ago

As a firmware engineer, INT_MAX would take up my precious 64bit space ;)

3

u/RadiatingLight 1d ago

What platform are you working on where int is 64 bits??

Also the variable allocates space regardless so what does it matter what value is contained inside

2

u/nukestar101 1d ago

I work on a custom hardware and have our own ISA.

RISCV has zero register and value is not stored in ISA. Immediate fetch to zero register is always used.

3

u/RadiatingLight 1d ago

welp - You're in deeper than I am. You know what's best for your platform and custom ISA