NO

Author Topic: Char Pointer After Char Array  (Read 12863 times)

Monolith

  • Guest
Char Pointer After Char Array
« on: July 02, 2012, 03:32:01 AM »
When putting a char pointer after a char array in a structure the expected char pointer type is char array.
Example:
Code: [Select]
typedef struct struct_t {
    char c[4];
    char *s;
} struct_t;

const struct_t test = {'1234', "Test"}; // <------- Compiler complains expecting 'char' but found 'char *'

Pelles C Version: 7 RC4
« Last Edit: July 02, 2012, 03:38:26 AM by Monolith »

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Char Pointer After Char Array
« Reply #1 on: July 02, 2012, 04:55:31 AM »
Seems more like a user error than a bug in Pelle's C...

You should actually get a warning 2055 before that error message you mentioned and that warning is a direct hint as to what you did wrong...

Ralf

CommonTater

  • Guest
Re: Char Pointer After Char Array
« Reply #2 on: July 02, 2012, 05:04:38 AM »
Also take note that in order to correctly store "1234" you need 5 characters not 4 in your c array... one for each of the characters and one for the trailing 0.


Monolith

  • Guest
Re: Char Pointer After Char Array
« Reply #3 on: July 02, 2012, 05:35:19 AM »
Oops, my bad. I don't know what you guys were saying, for that code I didn't get an error message 2055 and I used single quotes not double. Anyway, I have been programming in asm lately and I made a error in what you can set in single quote in C.

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Char Pointer After Char Array
« Reply #4 on: July 02, 2012, 05:37:32 AM »
Also take note that in order to correctly store "1234" you need 5 characters not 4 in your c array... one for each of the characters and one for the trailing 0.
Well, that's part of what the warning message that I mentioned would lead him too...  ;)

This is more a beginners question/issue than a compiler bug, courtesy of the "nice"  string handling capabilities of C (or better, the lack thereof)

Ralf

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Char Pointer After Char Array
« Reply #5 on: July 02, 2012, 05:40:09 AM »
Oops, my bad. I don't know what you guys were saying, for that code I didn't get an error message 2055 and I used single quotes not double. Anyway, I have been programming in asm lately and I made a error in what you can set in single quote in C.
It's not a "error" 2055, but a "warning". I suspect you have warnings disabled to not be bothered, though they are giving hints to improper programming.

Using double quotes alone isn't fixing the problem, you still need to increase the size of the array in that case in order to accommodate the terminating '/0' character...

Here's both the warning and the error message as they show up when put into a simple test project/program
Code: [Select]
Building C:\Documents and Settings\Ralf\My Documents\Pelles C Projects\monolith\output\monolith.obj.
C:\Documents and Settings\Ralf\My Documents\Pelles C Projects\monolith\monolith.c(6): warning #2055: Excess characters in 'char' character literal ignored.
C:\Documents and Settings\Ralf\My Documents\Pelles C Projects\monolith\monolith.c(6): error #2082: Invalid initialization type; expected 'char' but found 'char *'.
Ralf
« Last Edit: July 02, 2012, 05:43:22 AM by Bitbeisser »

CommonTater

  • Guest
Re: Char Pointer After Char Array
« Reply #6 on: July 02, 2012, 12:53:57 PM »
Oops, my bad. I don't know what you guys were saying, for that code I didn't get an error message 2055 and I used single quotes not double.

A suggestion...
Go into Project -> Project Options -> Compiler -> Warnings = Level 2
Make the report pane at the bottom of the IDE a bit bigger.

Now treat each warning as an error... something to be fixed.

The lesson is...  "Compiles" does not mean "Works".

 
Quote

Anyway, I have been programming in asm lately and I made a error in what you can set in single quote in C.

An ASM programmer should be keenly aware of the trailing 0 on every string, since he would most often have to put them there manually. 
 
 
« Last Edit: July 02, 2012, 01:04:20 PM by CommonTater »

Monolith

  • Guest
Re: Char Pointer After Char Array
« Reply #7 on: July 02, 2012, 07:31:42 PM »
Again, I am aware of the trailing zeros, that is why I used single quotes, not double. So I will not receive that warning message. In asm you can set all the fields at once, in C you cannot.
The correction would be:
Code: [Select]
const struct_t test = {'1','2','3','4',"Test"};

CommonTater

  • Guest
Re: Char Pointer After Char Array
« Reply #8 on: July 03, 2012, 02:45:29 AM »
Again, I am aware of the trailing zeros, that is why I used single quotes, not double. So I will not receive that warning message. In asm you can set all the fields at once, in C you cannot.
The correction would be:
Code: [Select]
const struct_t test = {'1','2','3','4',"Test"};

The thing is that you should want that trailing 0 in there.  It terminates the string so any of the string functions don't just run on and fill your screen with garbage when reading it.  C has no way to know the actual length of a string in advance and is totally dependent on that trailing 0 to know when to stop.  I've seen unterminated strings result in screen after screen of junk as puts() (etc.) runs on and on looking for that 0.

Your code sould say...
Code: [Select]
typedef struct struct_t {
    char c[5];
    char *s;
} struct_t;

const struct_t test = {"1234", "Test"};
« Last Edit: July 03, 2012, 02:47:24 AM by CommonTater »

Monolith

  • Guest
Re: Char Pointer After Char Array
« Reply #9 on: July 03, 2012, 03:49:30 AM »
Yes, a zero trail is needed to print strings; however, I never intended to print the string. Each of those char would have represented a byte of information, i.e. 'E' = perform "E" procedure. You could also think of it as using int8_t or uint8_t type.

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Char Pointer After Char Array
« Reply #10 on: July 03, 2012, 05:35:46 AM »
Again, I am aware of the trailing zeros, that is why I used single quotes, not double. So I will not receive that warning message.
Well, that is exactly the reason why you should receive that warning message!

Single quotes are for single characters only! Character arrays would use double quotes and then also require a trailing '\0' when writing them as constants...
Quote
In asm you can set all the fields at once, in C you cannot.
Correct, as assembler just treats them as single bytes, C is more "advanced" here and assumes proper string handling....
Quote
The correction would be:
Code: [Select]
const struct_t test = {'1','2','3','4',"Test"};
Depending on what you intended purpose is/was (and which isn't obvious by just teh snippet you posted), that would be indeed the correct way to so this....

Ralf

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Char Pointer After Char Array
« Reply #11 on: July 03, 2012, 05:38:10 AM »
The thing is that you should want that trailing 0 in there.
Well, no, not necessarily. You can use the four characters in the array just by them self, if you know that you have an array of fixed length and do not use them for any "string" purposes.

But as I mentioned in my previous post, his intention where less than obvious from just the posted snippet...

Ralf

Monolith

  • Guest
Re: Char Pointer After Char Array
« Reply #12 on: July 03, 2012, 07:05:29 AM »
Single quotes are for single characters only! Character arrays would use double quotes and then also require a trailing '\0' when writing them as constants...

Single quotes can be for multiple characters, for example if I wrote:

Code: [Select]
typedef struct struct_t {
    int c;
    char *s;
} struct_t;

static struct_t test = {'1234', "Test"};

This would be perfectly acceptable. However, I wanted to access each byte without >> and/or &.

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Char Pointer After Char Array
« Reply #13 on: July 03, 2012, 08:03:07 AM »
Single quotes are for single characters only! Character arrays would use double quotes and then also require a trailing '\0' when writing them as constants...

Single quotes can be for multiple characters, for example if I wrote:

Code: [Select]
typedef struct struct_t {
    int c;
    char *s;
} struct_t;

static struct_t test = {'1234', "Test"};

This would be perfectly acceptable. However, I wanted to access each byte without >> and/or &.
Sorry, but no, this is not correct.

Single quotes are for single characters only! For the above, with warnings enabled, you get the very same warning message
Code: [Select]
warning #2055: Excess characters in 'char' character literal ignored.And that warning tells you exactly what is wrong. You have "excess characters", it can't be much clearer.

That with warnings disabled the above code might compile and run does not change the fact that this is very bad code, simply relying on the side effects that allow this to 'look like working'. If you try this on a processor with a different endian and/or a larger default int (64bit), this code will fail!

Ralf

Monolith

  • Guest
Re: Char Pointer After Char Array
« Reply #14 on: July 03, 2012, 08:16:27 AM »
Enable Microsoft extensions...