[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: const char* typedefs
- From: Paige DePol <lual@...>
- Date: Wed, 7 Feb 2018 15:27:58 -0600
Sean Conner <sean@conman.org> wrote:
>
> int big_array[1024];
> int single_int;
> int *pa;
> int *pb;
> int *pc;
> int a;
> int b;
> int c;
> int d;
> int e;
>
> pa = big_array; // okay, big_array referenced here becomes a pointer
> pb = &big_array[0]; // the same as the above line
> pc = single_int; // error---single_int here just returns a value when a pointer is expected
> pc = &single_int; // this is fine
>
> a = *pa; // okay
> a = *big_array; // error---big_array is an array, not a pointer
> b = pa[0]; // same as "a = *pa"
> c = *pc; // also okay
> c = single_int; // still okay
> d = pc[0]; // again okay
> e = pa[2]; // okay, because pa points to big_array and index 2 exists
> e = pc[2]; // undefined bahavior, because pc points to
> // single_int, which is *NOT* an array.
>
> I'm not even going to go into the whole 2[pa] bit here ... but I hope I got
> across that pointers and arrays are not exactly the same thing.
As you mentioned, an error is generated if you try declaring 'big_array' as
an 'int *' in the header file and then try to implement it as 'int[5]':
error: redefinition of 'big_array' with a different type: 'int [5]' vs 'int *'
However, other than that error, the value of 'big_array' is still just a
pointer to the first element of the array once the header is changed to
declare the variable as 'int[]' instead of 'int *'.
I created some sample code using the following files: [1]
===== ack.h =====
extern int big_array[]; // Size not required here
===== ack.c =====
#include "ack.h"
int big_array[5] = { 5, 4, 3, 2, 1 }; // big_array now a pointer
===== oop.c =====
#include <stdio.h>
#include "ack.h"
int main() {
printf("a[%p] b[%p] c[%p]\n", big_array, &big_array[0], &(*big_array));
printf("a[%p] b[%p] c[%p]\n", big_array + 3, &big_array[3], &(*(big_array + 3)));
a = *big_array; // not an error is same as big_array[0]
b = *(big_array + 2); // ...and big_array[2]
c = *(big_array + 4); // ...and big_array[4]
printf("a[%d] b[%d] c[%d]\n", a, b, c);
printf("a[%d] b[%d] c[%d]\n", big_array[0], big_array[2], big_array[4]);
}
Compiling the above examples using 'cc oop.c ack.c -Wpedantic" generates no
errors or warnings, other than printf expecting void*, and generates this:
(obviously the pointer values will change between successive executions)
a[0x101193020] b[0x101193020] c[0x101193020]
a[0x10119302c] b[0x10119302c] c[0x10119302c]
a[5] b[3] c[1]
a[5] b[3] c[1]
Other than generating an error if you try to implement a static array into a
variable that was declared as a pointer, arrays themselves are pointers and
the [] notation is just syntactical sugar for pointer arithmetic... I mean
unless I am missing something really fundamental here about your examples?
> c = single_int; // still okay
This example generates a warning, however, as you are trying to assign an int
value to a pointer variable, which is probably not what you want to do.
warning: incompatible integer to pointer conversion assigning to 'int*' from 'int'
I don't know what you mean by "the whole 2[pa] bit" though, can you explain?
> In my opinion, it's lazy because you are doing so to save typing (again,
> subjective). For example, 'uchar' could be an 'unsigned char', but it could
> also be a 'UTF-8 character' (but why not 'utf8char' then? Because that's
> too much to type 8-P
According to Larry Wall being lazy is one of the three programmer virtues! [4]
>> All that said, I am getting the distinct impression that using a typedef for
>> C strings is something that should not be done... okay, more than just an
>> impression really. Seriously though, I will take everything that has been
>> said under advisement... this has been enlightening and I do appreciate all
>> the feedback as I would like to make my code as clean as possible.
>
> Again, that's subjective. I consider my code clean, but a friend of mine
> just can't comprehend it. On the flip side, he considers his code to be the
> hight of clarity yet I find it to be a maze of twisty uppercase typedefs,
> all alike (or to put it another way---it's trying to abstract the
> implementation from itself).
Well then, I guess I just have to decide if I want to be pragmatic or a purist
about any code smells in my source code. I may just decide to go the pragmatic
route as I don't necessarily think the purist mentality is always the best path.
To paraphrase the wiki [5]; The pragmatic view of CodeSmells is the connotation
of the word smell. If something smells, it definitely needs to be checked out,
but it may not actually need fixing or might have to just be tolerated.
~Paige
[1] I use 'ack' and 'oop' [2] much as others use 'foo' and 'bar'.
[2] Originated from Bill the Cat [3] of Bloom County fame.
[3] https://en.wikipedia.org/wiki/Bill_the_Cat
[4] http://threevirtues.com
[5] http://wiki.c2.com/?CodeSmell