Author Topic: C Code Problem (2)  (Read 14426 times)

0 Members and 1 Guest are viewing this topic.

Offline helius

  • Super Contributor
  • ***
  • Posts: 3642
  • Country: us
Re: C Code Problem (2)
« Reply #25 on: February 03, 2015, 04:07:24 am »
yep it is better show that it might change somewhere in the code, so forget about const and make it static ...

the 'static' storage class is one of the worst-named features of C. as another poster said, it means two completely different things depending on the scope of the identifier. please don't treat it as an "alternative" to 'const'  :palm:

Also, '\0' and 0 are the same according to the specification.
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: C Code Problem (2)
« Reply #26 on: February 03, 2015, 08:07:07 am »
Quote
the 'static' storage class is one of the worst-named features of C. as another poster said, it means two completely different things depending on the scope of the identifier. please don't treat it as an "alternative" to 'const'  :palm:

Nod

But it is, in the end, just a keyword in the language and it is pretty simple to learn what it means.
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 3642
  • Country: us
Re: C Code Problem (2)
« Reply #27 on: February 03, 2015, 08:19:39 am »
That's all true, but the way those keywords control visibility and external linkage is in my opinion too prone to error and not very powerful. Ada, Modula 3, and Oz got it right.
 

Offline eneuro

  • Super Contributor
  • ***
  • Posts: 1528
  • Country: 00
Re: C Code Problem (2)
« Reply #28 on: February 03, 2015, 08:35:52 am »
Also, '\0' and 0 are the same according to the specification.
Probably you should read one of classic C language books first and have longer programming experience.
There are many architectures and then one day you will find out why better use '\0' sometimes  :-DD
12oV4dWZCAia7vXBzQzBF9wAt1U3JWZkpk
“Let the future tell the truth, and evaluate each one according to his work and accomplishments. The present is theirs; the future, for which I have really worked, is mine”  - Nikola Tesla
-||-|-
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: C Code Problem (2)
« Reply #29 on: February 03, 2015, 10:03:03 am »
Quote
That's all true, but the way those keywords control visibility and external linkage is in my opinion too prone to error and not very powerful. Ada, Modula 3, and Oz got it right.
Oz is a new one on me but a quick look at Wikipedia suggests it was developed in an academic environment, Ada and Modula 3 are, of course huge designed-by-committee languages.

C on the other hand, was originally part of the pet project of a couple of researchers on an old 16 bit system. It's not that surprising some things were rough and ready but it is a testament to the basic soundness and (more important) utility of the language that we are discussing it almost 50 years later.
 

Offline DJohn

  • Regular Contributor
  • *
  • Posts: 103
  • Country: gb
Re: C Code Problem (2)
« Reply #30 on: February 03, 2015, 11:50:54 am »
Also, '\0' and 0 are the same according to the specification.
Probably you should read one of classic C language books first and have longer programming experience.
There are many architectures and then one day you will find out why better use '\0' sometimes  :-DD

Or we could just read the specification.  '\0' is a constant of type int, value 0 (it's not a char).  0 is also constant of type int, value 0.  Helius is right - they're the same.  If you've got a compiler/target combination where they're different, you should complain to whoever sold it to you.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: C Code Problem (2)
« Reply #31 on: February 03, 2015, 11:51:24 am »
Quote
Anything with an MMU should be able to mark pages read-only and fault if written to if the MMU is being used.

Let me restate the question you just answered: on what CPUs would the use of "static char bat[]= "Bat";" cause bus fault?
================================
https://dannyelectronics.wordpress.com/
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: C Code Problem (2)
« Reply #32 on: February 03, 2015, 12:16:30 pm »
Quote
Let me restate the question you just answered: on what CPUs would the use of "static char bat[]= "Bat";" cause bus fault?

Asked like that - none, I hope, since that is an initialisation and as I said earlier if you couldn't initialise a const variable they would be pointless.

In any case I thought the question was about assignment, not initialisation, specifically writing to a character location within a "const" string.

IF you said
Code: [Select]
const char bat[] = "Bat"; 

and later tried
Code: [Select]
bat[sizeof(bat)-1]= '\0';

As was suggested in an earlier post then that would be invalid code, and what happens is a bit system dependant, however, typically in a system using paged virtual memory where the compiler places the constant bat in a read-only page you will get a page fault.

Smaller systems without MMU might generate a bus fault, it's logical enough to do so with an invalid write but it's as much system dependant as CPU dependant and I suspect most such systems simply ignore the write.

 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: C Code Problem (2)
« Reply #33 on: February 03, 2015, 12:23:11 pm »
Quote
that would be invalid code

Think about the difference between "const unsigned char *" and "* const unsigned char".

Many of the embedded compilers are wrong when it comes to "const" implementation, for good reasons overall.
« Last Edit: February 03, 2015, 12:24:43 pm by dannyf »
================================
https://dannyelectronics.wordpress.com/
 

Offline eneuro

  • Super Contributor
  • ***
  • Posts: 1528
  • Country: 00
Re: C Code Problem (2)
« Reply #34 on: February 03, 2015, 12:34:13 pm »
If you've got a compiler/target combination where they're different, you should complain to whoever sold it to you.
I do not have to complain while I know what I'm doing  :-DD

How will you explain that something which should be the same doesn't fit into your theory and  sizeof('\0') != sizeof(0)  ... different in C++?  >:D

« Last Edit: February 03, 2015, 12:36:28 pm by eneuro »
12oV4dWZCAia7vXBzQzBF9wAt1U3JWZkpk
“Let the future tell the truth, and evaluate each one according to his work and accomplishments. The present is theirs; the future, for which I have really worked, is mine”  - Nikola Tesla
-||-|-
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: C Code Problem (2)
« Reply #35 on: February 03, 2015, 12:40:17 pm »
Quote
Think about the difference between "const unsigned char *" and "* const unsigned char".

But now you are shifting the goalposts somewhat are you not?

If you say
Code: [Select]
const char bat[] = "Bat"; 
then the values in the array are "const" & the array name itself is not an lvalue.

If you say
Code: [Select]
const unsigned char *bat = "Bat"; 
OR

Code: [Select]
unsigned char * const ball = "Ball"; 

Then
1) you now have two things, a pointer and a string literal
2) the type of the literal differs in Ansi C (char[]) vs C++ (const char[])
3) what is "const" differs - in the first example the content is immutable (pointer to const char)
    in the second the pointer is immutable (const pointer to char).

I used to be good at this language lawyer type stuff but as I no longer code for a living I'm getting slightly rusty :)


« Last Edit: February 03, 2015, 12:45:40 pm by grumpydoc »
 

Offline DJohn

  • Regular Contributor
  • *
  • Posts: 103
  • Country: gb
Re: C Code Problem (2)
« Reply #36 on: February 03, 2015, 01:15:58 pm »
How will you explain that something which should be the same doesn't fit into your theory and  sizeof('\0') != sizeof(0)  ... different in C++?  >:D

But we weren't talking about C++ were we?  The thread is about C, and you explicitly mentioned "classic C language books".

In C++, yes '\0' is of type char.  It still has value 0, though, and if buffer is an array of chars,
Code: [Select]
buffer[n] = '\0';
and
Code: [Select]
buffer[n] = 0;
have identical effect.  You're free to consider the first to be better style, but there is no observable difference in behaviour.

Quote from: dannyf
Let me restate the question you just answered: on what CPUs would the use of "static char bat[]= "Bat";" cause bus fault?
I no longer have a devkit on my desk to test it, but from memory on Playstation 3 that would result in bat being initialised as a pointer to some data in the .rodata segment, which is read-only.  Attempting to modify it later would cause a bus fault.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: C Code Problem (2)
« Reply #37 on: February 03, 2015, 01:19:20 pm »
Quote
But now you are shifting the goalposts somewhat are you not?

No. I thought the original discussion was over when you said you couldn't find a cpu where the said sentence would create a bus fault - the assertion you had earlier.

My attempt was just trying to provide you with a better understand of what that initialization was really meant.
================================
https://dannyelectronics.wordpress.com/
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: C Code Problem (2)
« Reply #38 on: February 03, 2015, 01:36:14 pm »
Quote
But now you are shifting the goalposts somewhat are you not?

No. I thought the original discussion was over when you said you couldn't find a cpu where the said sentence would create a bus fault - the assertion you had earlier.

No, I did not make that assertion - donotdespisethesnake did

I did describe faults that might occur from writing to read only memory and circumstances where I might expect a bus fault - slightly different :)

Quote
My attempt was just trying to provide you with a better understand of what that initialization was really meant.

My understanding of initialisation vs assignment and the constness of variables is just fine, thanks.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: C Code Problem (2)
« Reply #39 on: February 03, 2015, 01:37:40 pm »
Quote
My understanding of initialisation vs assignment and the constness of variables is just fine,

You think it is fine and it is fine are two separate things, :)
================================
https://dannyelectronics.wordpress.com/
 

Offline DigibinTopic starter

  • Regular Contributor
  • *
  • Posts: 90
Re: C Code Problem (2)
« Reply #40 on: February 03, 2015, 09:21:30 pm »
There's no real advantage to using int8_t anyway.

Does it not save memory by using a single byte rather than the two that int uses?

Why not do it with one loop to build the string and one to "move" the '<>' and try to make everything work automatically should someone come along and change the message.

E.g.
Code: [Select]
static const char bat[] = "   Bat  "; // Splash screen text, top line
char buffer[sizeof(bat)]; // Buffer string to manipulate bat and box
int l = strlen(bat);
int i, h;

for (h=1; h <= l/2; h++) {
  for (i=0; i < l; i++)
  {
    if (i < l/2-h || i > l/2+h-1) {
      buffer[i] = ' ';
    } else if (i == l/2-h) {
      buffer[i] = '<';
    } else if (i == l/2+h-1) {
      buffer[i] = '>';
    } else {
      buffer[i] = bat[i];
    }
  }
  buffer[i] = '\0';
   
  lcd_gotoxy(0,0);       // Go to first line
  lcd_puts(buffer);       // Put string to display
  _delay_ms(1000);
  lcd_clrscr();       // Clear display
}

This works perfectly, thank you! I did think to try and do it like this somehow but couldn't figure out how to actually implement it. Looks easy now I've seen it.

So back to my original point - the strcpy function somehow broke my code. No idea how, no compiler warnings or anything. Still interested to know why, if anyone has any more ideas.
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11885
  • Country: us
Re: C Code Problem (2)
« Reply #41 on: February 03, 2015, 09:41:55 pm »
So back to my original point - the strcpy function somehow broke my code. No idea how, no compiler warnings or anything. Still interested to know why, if anyone has any more ideas.

You wrote strcpy above, yet you used strncpy in your original code sample.

If you simply do this, does it work?
Code: [Select]
    const char bat[] = "   Bat   ";
    char buffer[]    = "   Bat   "; /* one way to make buffer same size as bat */
    ...
    strcpy(buffer, bat);
    ...
    lcd_puts(buffer);
    ...
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: C Code Problem (2)
« Reply #42 on: February 03, 2015, 09:59:48 pm »
Quote
You think it is fine and it is fine are two separate things
Smiley or not I'm afraid the only way I read that is as an insult. Exactly what do you think I misunderstand?

Would you care to give us the benefit of your vast intellect in the form of an explanation rather than snide comments?

There's no real advantage to using int8_t anyway.

Does it not save memory by using a single byte rather than the two that int uses?

Ah, going back to your original post I see you are on an ATtiny48 so there probably is some merit in sticking to 8 bit types if you don't need bigger.
« Last Edit: February 03, 2015, 10:02:45 pm by grumpydoc »
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: C Code Problem (2)
« Reply #43 on: February 04, 2015, 08:39:01 am »
Quote
const unsigned char *bat = "Bat"; 
In particular, some compiler setups for chips with von Neumann architectures use "const" as the "put this variable in flash instead of RAM" control, and subsequent attempts to write to them will result in illegal memory access traps.  (I'm pretty sure that gcc for ARM is one example.  Probably controlled by the linker maps.)
 

Offline BloodyCactus

  • Frequent Contributor
  • **
  • Posts: 482
  • Country: us
    • Kråketær
Re: C Code Problem (2)
« Reply #44 on: February 04, 2015, 05:54:43 pm »
I remember one compiler would put const strings/data into the .text segment and non const strings/data into the .data section. Another compiler would put ALL the things into .text, broke a lot of old style C that assumed strings were mutable and things using strtok would break all over the show, then gcc showed up and you had the "-fwritable-strings" option...

-- Aussie living in the USA --
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C Code Problem (2)
« Reply #45 on: February 04, 2015, 07:24:27 pm »
Quote
const unsigned char *bat = "Bat"; 
In particular, some compiler setups for chips with von Neumann architectures use "const" as the "put this variable in flash instead of RAM" control
That is because you just described these rules:
- I am allowed to change bat.
- I shall not change *bat.
But, since you made the rules, you can break the rules. Welcome to C.

Otherwise you can use: "static const char * const" which forbids about everything I can think of now.
Easier (not better) would be to make your constants using a #define. Since the compiler is somewhat smart, I should notice that all the literals placed by the preprocessor are identical, and thus only allocate the memory once. If run with the correct options of course.
Writing to literals is never allowed, for obvious reasons.
 

Offline DJohn

  • Regular Contributor
  • *
  • Posts: 103
  • Country: gb
Re: C Code Problem (2)
« Reply #46 on: February 05, 2015, 10:47:31 am »
Just a thought: this is AVR, and AVR is Harvard, and you use different instructions to access RAM and ROM.  If the string is ending up in ROM, strncpy won't be able to see it.  It's been long enough since I last used one that I can't remember exactly what happens in this situation.

If you copy bytes manually from bat to buffer, instead of using strncpy, do you get "Bat" on the screen?  If you get garbage, this will be why.

I've got a project at home somewhere that does similar things.  If I remember tonight, I'll dig it up and see what tricks it had to use.

Code: [Select]
char bat[] = "12345678";
char buffer[9];
strncpy( buffer, bat, 8 );
This will copy the first 8 bytes from bat to buffer, then stop.  It won't append a zero, because strncpy is a nasty little function that loves to surprise you.  If you
Code: [Select]
buffer[8] = 0;
yourself, then all should be good.  But your memset is doing that, so I don't know what's going wrong.
 

Offline DJohn

  • Regular Contributor
  • *
  • Posts: 103
  • Country: gb
Re: C Code Problem (2)
« Reply #47 on: February 05, 2015, 06:11:10 pm »
Just a thought: this is AVR, and AVR is Harvard, and you use different instructions to access RAM and ROM.  If the string is ending up in ROM, strncpy won't be able to see it.  It's been long enough since I last used one that I can't remember exactly what happens in this situation.

No, it looks like string literals (and other data) get copied to RAM unless you specifically request that they stay in ROM.  Whatever the problem is, it's not that.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C Code Problem (2)
« Reply #48 on: February 05, 2015, 08:26:26 pm »
Just a thought: this is AVR, and AVR is Harvard, and you use different instructions to access RAM and ROM.
I do remember something with pgmspace instrinsics, does that still apply?
http://www.nongnu.org/avr-libc/user-manual/pgmspace.html
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf