Thread: What type is a macro constant?

  1. #1
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181

    What type is a macro constant?

    As the title says.
    If you have to put number <define> NUMBER 125 it will assign to it an int type because its somehow "best fit"? or if NUMBER was 160.5 itll assign float? Or its somehow type free?

    And what if its a 1 or 0. Itll automaticall put it in a bit field byte?

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Macros/defines are preprocessor directives.

    C preprocessor - Wikipedia, the free encyclopedia

    Before anything is compiled, the preprocessor literally goes thru your source and replaces "NUMBER" with whatever it is defined as. So if you have this:

    Code:
    #define NUMBER 160.5
    int x = NUMBER;
    When it gets to the compiler it will be:

    Code:
    int = 160.5
    Assigning a double to an int just rounds the double down.
    Last edited by MK27; 09-08-2011 at 10:37 AM. Reason: I'z wrong
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Macros are replaced with their defined expressions by the preprocessor. You can infer the resulting type from the defined expression and other surrounding expressions.

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    There is no assignment. NUMBER will be replaced with 125, which is an int (integer constants have type int unless they're too large). If you have #define NUMBER 160.5, then NUMBER will be replaced with 160.5, which is a double.

    Macros do not have a type. Macros are essentially search and replace, which means macros don't really exist as far as the compiler is concerned (they disappear after pre-processing). If it's 1 or 0, the type will be int, because 1 and 0 are ints.

    This can be somewhat problematic:
    Code:
    #define MAX 100000
    So when you use MAX in your code, will it have (or be replaced with an expression that has) the type int? Maybe. But what if int is 16 bits? Then 100000 will be a long. This isn't usually going to be a problem, but is something to watch out for.

    Quick answer: The type of a macro (conceptually) is the type of the expression that you used to define your macro.

  5. #5
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Doh! Stupid question.

    Does this substitution concept work the same way with enumerations or are enumerations ints?

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    enums are their own type. For example.

    Code:
     enum state_t {NORMAL_STATE, COMMENT_STATE, BLOCK_COMMENT_STATE, STRING_STATE, CHAR_STATE};
    If you omit a type name, it is an anonymous type, just like similar unions or structs. C's type safety rules are lax enough that it often makes no practical difference, though.

  7. #7
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Another thing. a Macro constant applied to bit fields... Would you simply define a bit flag like any other constant?:

    <define> KEYWORD 01

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by MK27 View Post
    WRT macro functions, the preprocessor substitutes the outcome of the function, not the actual code.
    Nope! it plugs in the code that the macro function stands for.

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Another thing. a Macro constant applied to bit fields... Would you simply define a bit flag like any other constant?:

    <define> KEYWORD 01
    I've never actually used bit fields, but I don't see why it wouldn't work.

    FYI, 01 is an octal number.

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Vespasian View Post
    Another thing. a Macro constant applied to bit fields... Would you simply define a bit flag like any other constant?:

    <define> KEYWORD 01
    Yeah, I do it all the time, and so does the standard library.

    Code:
    /* bit flags for blah blah */
    #define READ 1
    #define WRITE 2
    #define HOLD 4
    #define WARN 8
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by Vespasian View Post
    Another thing. a Macro constant applied to bit fields... Would you simply define a bit flag like any other constant?:

    <define> KEYWORD 01
    That wouldn't create a bit-field, tho' a 2 bit wide field can be initialized to that value.


    [Edit] Never mind I didn't read the post right.

  12. #12
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Vespasian View Post
    Another thing. a Macro constant applied to bit fields... Would you simply define a bit flag like any other constant?:

    <define> KEYWORD 01
    As whiteflags pointed out, yes, 01 would work, and yes, it is an octal number. When people define offsets for bitfields, some use octal, but most of them use hex or bit-shifting:
    Code:
    #define USING_HEX_BIT_0    0x01
    #define USING_HEX_BIT_1    0x02
    #define USING_HEX_BIT_2    0x04
    #define USING_HEX_BIT_3    0x08
    
    #define BIT_SHIFT_BIT_0    1 << 0
    #define BIT_SHIFT_BIT_1    1 << 1
    #define BIT_SHIFT_BIT_2    1 << 2
    #define BIT_SHIFT_BIT_3    1 << 3
    The advantage of the second method is that you can easily see what bit number you're using by looking at the 0, 1, 2, 3, versus having to translate from hex. This can make a difference when you start getting above bit number 8 or 16, and your hex constants become quite long.

  13. #13
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Theres some sick stuff on bit fields. K&R admitedly says that the full details cant be delved into. Theres other features of "padding" etc... wtf. Any good online tuts for C bit fiddling?

  14. #14
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Vespasian View Post
    Theres some sick stuff on bit fields. K&R admitedly says that the full details cant be delved into.
    That's crazy. I know they may seem mysterious when you first learn about them, but they are pretty darn simple in IMHO. Altho I have seen some programming blogs, etc, where whoever says they don't like bitfields because they are "too arcane" or something. Ridiculous. Pure hype. It's like calling basic arithmetic incomprehensible.

    I really like bit fields. 95% of using them for me involves one of three operations:

    Code:
    #define FLAG 1
    int field = 0;
    
    // set flag
    field |= FLAG;
    
    // check if flag is set
    if (field & FLAG) ....
    
    // unset bit if set
    void unset (int field, int flag) {
         if (field & flag) field ^= flag;
    }
    
    unset(field, FLAG);
    That and anduril462's point about using << shift in the #define are most of what you need to understand. Google "C bit operations" and you should find plenty more if you want, eg:

    http://www.cprogramming.com/tutorial...operators.html
    Last edited by MK27; 09-08-2011 at 11:04 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #15
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    On the other hand, there is also this thing called bitfields which are a specialization of structs.
    Quote Originally Posted by Wikipedia
    Kernighan and Ritchie's book, The C Programming Language, describes a method for defining and accessing fields directly. Using this method, bitwise operators are not needed as bit members can be accessed the same as members of a structure without the need to create a object-oriented class like the one above. An example using C's struct keyword and C++'s bool data type follows:

    Code:
    typedef struct Preferences {
        bool likesIceCream : 1;
        bool playsGolf     : 1;
        bool watchesTv     : 1;
        bool readsBooks    : 1;
    } Preferences; 
     
    Preferences fred;
    fred.likesIceCream = true;
    fred.playsGolf     = true;
    fred.watchesTv     = true;
    fred.readsBooks    = false;
     
    if (fred.likesIceCream) {
        /* ... */
    }
    Which is the entire reason I said I haven't use them before.

    I actually learned all about bits without understanding they were "fields". I think I will be able to go my entire career and never have to use bit fields. However,
    Theres other features of "padding" etc... wtf.
    There is such a thing as a "packed struct" and that is when you start caring about padding and byte alignment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 05-23-2011, 02:04 PM
  2. Is it possible to set type for define macro?
    By 6tr6tr in forum C++ Programming
    Replies: 5
    Last Post: 04-16-2008, 01:32 PM
  3. integer constant is too large for type
    By Abda92 in forum C++ Programming
    Replies: 8
    Last Post: 02-09-2008, 11:47 AM
  4. Why make a constant a constant again?
    By Overworked_PhD in forum C Programming
    Replies: 3
    Last Post: 11-03-2007, 06:57 PM
  5. Constant pointer to constant value
    By tretton in forum C Programming
    Replies: 10
    Last Post: 12-23-2005, 01:45 PM