Thread: ROM Qualifier (Part 2)

  1. #1
    Registered User
    Join Date
    Aug 2010
    Location
    Rochester, NY
    Posts
    196

    ROM Qualifier (Part 2)

    Hey,

    I originally had a post here, but it got locked against my wishes.

    ROM Qualifier vs Const?

    The mod got annoyed because somebody was bumping an old topic, which is understandable, but that bump was exactly the type of answer I was looking for, and would like to inquire further.

    In accordance with post #20.
    - Okay, so this is JUST a micro controller thing, that makes sense, I saw it on a micro controller..I suppose I should have stated that, but I didn't think it was anything outside the realm of the C language.
    - So then for MC's, does it do anything different than const would? (back to the original thread's title). Sure, it sticks it into ROM, but doesn't const, also, so to speak?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,663
    No, they're still different things.

    Consider these uses of const counter examples.
    Code:
    const volatile unsigned long int clock;
    // the hardware is going to change clock all the time, but
    // this code is not allowed to write to it to change the time.
    
    for ( int i = 1 ; i < 5 ; i++ ) {
        const unsigned long end = clock + 2 * i;
        // end varies with each loop, but should not be changed within the loop
        // In other words, it is initialised, but it cannot be assigned later.
        while ( clock < end );
    }
    Neither of these could be placed in ROM.


    Perhaps you could hint at what post #20 said that my post #6 didn't.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Aug 2010
    Location
    Rochester, NY
    Posts
    196
    Quote Originally Posted by Salem View Post
    No, they're still different things.

    Consider these uses of const counter examples.
    Code:
    const volatile unsigned long int clock;
    // the hardware is going to change clock all the time, but
    // this code is not allowed to write to it to change the time.
    
    for ( int i = 1 ; i < 5 ; i++ ) {
        const unsigned long end = clock + 2 * i;
        // end varies with each loop, but should not be changed within the loop
        // In other words, it is initialised, but it cannot be assigned later.
        while ( clock < end );
    }
    Neither of these could be placed in ROM.
    Hrm, true. I thought const variables were declared in the program's code space? I mean obviously, your example shows that they can't, and that's true, but I thought const did something more than just make it un-mutatable, which is why "#define's are bad" as so many people say. Is that only in C++? Meaning in C it ONLY means they're not mutatable? Or will C put global const's in the code section?

    Also, what does volatile mean, I know I've seen that before :-\.

    Quote Originally Posted by Salem View Post
    Perhaps you could hint at what post #20 said that my post #6 didn't.
    It simply sounded as if you weren't sure, simply posing the idea. Wasn't personal =).

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,663
    In C, const is little more than "warn me if I try to change this". Whether a const makes it into the code space is really down to whatever implementation you're using. If your implementation is incapable of making such a choice, then adding the 'rom' keyword neatly solves the problem.


    > which is why "#define's are bad" as so many people say. Is that only in C++?
    Well in C++, you can use const like this
    Code:
    const int size = 10;
    int myArray[size];
    You cannot do this in C, so you have to use #define size 10 instead.

    The other major use of macros (in C) is to write short blocks of code in one form or another, like
    #define max(a,b) a > b ? a : b
    In C++, inline functions and templates pretty much cover anything you could do with pre-processor magic.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Syndacate View Post
    Also, what does volatile mean, I know I've seen that before :-\.
    It means "something is allowed to change this, and probably will be, but it's probably not me that's doing it".


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Aug 2010
    Location
    Rochester, NY
    Posts
    196
    Quote Originally Posted by Salem View Post
    In C, const is little more than "warn me if I try to change this". Whether a const makes it into the code space is really down to whatever implementation you're using. If your implementation is incapable of making such a choice, then adding the 'rom' keyword neatly solves the problem.


    > which is why "#define's are bad" as so many people say. Is that only in C++?
    Well in C++, you can use const like this
    Code:
    const int size = 10;
    int myArray[size];
    You cannot do this in C, so you have to use #define size 10 instead.
    You can't? I just did it perfectly fine. Didn't even kick it into C99 mode, whatever the default is in cygwin, compiled and ran like a champ.

    EDIT:
    I checked c89 mode, which is ISO C90, (the default is ISO C90 w/ GNU extensions), as well as ansi C, both compile fine.
    /EDIT

    Quote Originally Posted by Salem View Post
    The other major use of macros (in C) is to write short blocks of code in one form or another, like
    #define max(a,b) a > b ? a : b
    In C++, inline functions and templates pretty much cover anything you could do with pre-processor magic.
    Well sure, inline functions are great, especially if they're accessors or mutators to a class, but I would still use a macro for something like that..

    I think the excuse that "inline functions are better because they do type checking" is a horrible one, because if you screw it up in C, after the PP inserts the macro into the code, you'll get a compilation error soon after.

    Quote Originally Posted by quzah View Post
    It means "something is allowed to change this, and probably will be, but it's probably not me that's doing it".


    Quzah.
    Well can't that happen with any variable that somebody else has access to? You always have dangers like that, especially in a multi-threaded environment. Isn't it the same concepts surrounding the idea of resource locking? What does C do when it sees the 'volatile' modifier, not much it can do about it at compile time..
    Last edited by Syndacate; 02-06-2011 at 03:51 PM.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,663
    You probably created a VLA instead.

    This doesn't work.
    Code:
    $ cat bar.c
    #include <stdio.h>
    
    const int size = 10;
    int array[size];
    int main ( ) {
      return 0;
    }
    $ gcc bar.c
    bar.c:4: error: variably modified ‘array’ at file scope
    > but I would still use a macro for something like that
    Why?
    If you don't like the type checking argument, how about the freedom from side effects argument?
    Code:
    $ cat bar.c
    #include <stdio.h>
    
    #define max(a,b) a > b ? a : b
    
    int main ( ) {
      char *p = max("hello","world");
      int a = 10, b = 20;
      int c = max(a++,b++);
      printf("%s\n",p);
      printf("%d %d\n",a,b);
      return 0;
    }
    $ gcc bar.c
    $ ./a.out 
    hello
    11 22
    > because if you screw it up in C, after the PP inserts the macro into the code, you'll get a compilation error soon after.
    Oddly, doing max on two strings produced no such errors.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Aug 2010
    Location
    Rochester, NY
    Posts
    196
    Quote Originally Posted by Salem View Post
    You probably created a VLA instead.

    This doesn't work.
    Code:
    $ cat bar.c
    #include <stdio.h>
    
    const int size = 10;
    int array[size];
    int main ( ) {
      return 0;
    }
    $ gcc bar.c
    bar.c:4: error: variably modified ‘array’ at file scope
    Ah, okay, I wasn't making the array in the global scope. Not sure what a VLA is, though.

    I still don't see what's so great about it, over a macro. If I'm understanding it right, C++ in the global scope will stick a const var in the data section...and a string literal will be in the data section..no? I'm not seeing what's so bad about using a #define, though, even if the const version DOES work in C++. And if that stupid quote "It's the C++ way, not the C way" is the only rationale, that's just stupid.

    Quote Originally Posted by Salem View Post
    > but I would still use a macro for something like that
    Why?
    If you don't like the type checking argument, how about the freedom from side effects argument?
    Code:
    $ cat bar.c
    #include <stdio.h>
    
    #define max(a,b) a > b ? a : b
    
    int main ( ) {
      char *p = max("hello","world");
      int a = 10, b = 20;
      int c = max(a++,b++);
      printf("%s\n",p);
      printf("%d %d\n",a,b);
      return 0;
    }
    $ gcc bar.c
    $ ./a.out 
    hello
    11 22
    > because if you screw it up in C, after the PP inserts the macro into the code, you'll get a compilation error soon after.
    Oddly, doing max on two strings produced no such errors.
    Eh, IMO those side-effects are what happens when you have power. And I've continuously heard the threat of these 'nasty side-effects' - but I've never actually seen it happen IRL. In my experience, it just doesn't happen. Typically people capitalize macros to remove ambiguity, and people don't use them in the wrong place.

    As for the code above. A pointer is just a numeric value representing a memory address of an 'object' (no, not the OO definition of an object), on most systems it fits into the same space as an int. Because of this, you can compare two pointers based on their numeric value (ie. memory address that they're pointing to).

    Code:
    #define max(a,b) a > b ? a : b
    #include <stdio.h>
    int main ( ) {
        char* H = "Hello";
        char* W = "World";
        printf("Hello=%p :: World=%p\n", H, W);
        printf("%p\n", max(H, W));
    }
    Outputs:

    Code:
    $ ./a.exe
    Hello=0x402000 :: World=0x402006
    0x402006
    Because you're literally doing:
    if memory addr a is > memory addr b, return a, else, return b

    Works as expected.
    Last edited by Syndacate; 02-06-2011 at 04:23 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to get domain part from URL
    By George2 in forum C# Programming
    Replies: 2
    Last Post: 07-23-2008, 12:06 PM
  2. How to get a part of a string from a point onwards
    By pseudonoma in forum C Programming
    Replies: 2
    Last Post: 03-22-2008, 04:09 PM
  3. Replies: 9
    Last Post: 07-11-2006, 04:28 AM
  4. Suspicious Pointer Conversion
    By mr_spanky202 in forum C Programming
    Replies: 35
    Last Post: 04-11-2003, 12:35 PM