Re: a macro problem

Discussion in 'C Programming' started by Ian Collins, Oct 14, 2010.

  1. Ian Collins

    Ian Collins Guest

    On 10/15/10 08:14 AM, Davide wrote:
    > Hello comp.lang.c,
    > I'm a guy from Italy. First of all, sorry for my English :)
    > I'm attending a one-semester course in "Foundations of Programming".
    > We use the C language and "A book on C", 4th edition, by Kelley-Pohl.
    >
    > At some point at the beginning of the book there is an example,
    > the header file "pacific_sea.h". Inside this file, there is the line:
    >
    > #define SQ_FEET_PER_SQ_MILE (5280 * 5280)
    >
    > Here is my problem: the book says that writing 27878400 would be the
    > same. This is what my teacher says too. He says that (5280 * 5280)
    > will be automatically promoted to a type that fits that product.


    As the other replies have said, that is incorrect.

    Unless SQ_FEET_PER_SQ_MILE is required to be a compile time constant, it
    is much clearer and less error prone to write:

    const size_t sq_feet_per_sq_mile = 5280 * 5280;

    --
    Ian Collins
    Ian Collins, Oct 14, 2010
    #1
    1. Advertising

  2. Ian Collins <> writes:
    > On 10/15/10 08:14 AM, Davide wrote:
    >> Hello comp.lang.c,
    >> I'm a guy from Italy. First of all, sorry for my English :)
    >> I'm attending a one-semester course in "Foundations of Programming".
    >> We use the C language and "A book on C", 4th edition, by Kelley-Pohl.
    >>
    >> At some point at the beginning of the book there is an example,
    >> the header file "pacific_sea.h". Inside this file, there is the line:
    >>
    >> #define SQ_FEET_PER_SQ_MILE (5280 * 5280)
    >>
    >> Here is my problem: the book says that writing 27878400 would be the
    >> same. This is what my teacher says too. He says that (5280 * 5280)
    >> will be automatically promoted to a type that fits that product.

    >
    > As the other replies have said, that is incorrect.
    >
    > Unless SQ_FEET_PER_SQ_MILE is required to be a compile time constant, it
    > is much clearer and less error prone to write:
    >
    > const size_t sq_feet_per_sq_mile = 5280 * 5280;


    That still overflows if INT_MAX < 5280*5280.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Oct 14, 2010
    #2
    1. Advertising

  3. Davide <> writes:
    > Ian Collins wrote:
    >> On 10/15/10 08:14 AM, Davide wrote:
    >>> Hello comp.lang.c,
    >>> I'm a guy from Italy. First of all, sorry for my English :)
    >>> I'm attending a one-semester course in "Foundations of Programming".
    >>> We use the C language and "A book on C", 4th edition, by Kelley-Pohl.
    >>>
    >>> At some point at the beginning of the book there is an example,
    >>> the header file "pacific_sea.h". Inside this file, there is the line:
    >>>
    >>> #define SQ_FEET_PER_SQ_MILE (5280 * 5280)
    >>>
    >>> Here is my problem: the book says that writing 27878400 would be the
    >>> same. This is what my teacher says too. He says that (5280 * 5280)
    >>> will be automatically promoted to a type that fits that product.

    >>
    >> As the other replies have said, that is incorrect.
    >>
    >> Unless SQ_FEET_PER_SQ_MILE is required to be a compile time constant, it
    >> is much clearer and less error prone to write:
    >>
    >> const size_t sq_feet_per_sq_mile = 5280 * 5280;

    >
    > Thank you, for your reply. But the max for size_t could be
    > 65535, am I wrong? And the risk of overflow, according to what
    > Keith Thompson said, still holds.


    Right. size_t is for measuring sizes of objects; it's not
    necessarily big enough to hold numbers of something in the real
    world. No object in your program can be bigger than size_t bytes[*];
    size_t is also safe for array indices (since array elements are at
    least one byte). But even file sizes can exceed SIZE_MAX bytes.
    Picking the right type for what you're measuring can be tricky,
    and there's no really good general technique.

    You're not likely to run into a system with SIZE_MAX as small
    as 65535, but IMHO it's good to write code that's just a little
    more portable than it needs to be.

    > Maybe const long sq_feet_per_sq_mile = 5280 * 5280L;


    That would be safe, given the language guarantee that
    LONG_MAX >= 2**31-1. (But I'd put the "L" suffix on both
    constants, just for consistency.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Oct 14, 2010
    #3
  4. Ian Collins

    Ian Collins Guest

    On 10/15/10 10:49 AM, Davide wrote:
    >
    > Sorry if I change subject. But, since malloc takes an argument
    > of type size_t, does it mean that I should declare several mallocS
    > if I wanted to allocate more than 65535 bytes in a safe way?


    No. If you need more than can be allocated, you don't have enough memory!

    --
    Ian Collins
    Ian Collins, Oct 14, 2010
    #4
  5. Davide <> writes:
    [...]
    > Sorry if I change subject. But, since malloc takes an argument
    > of type size_t, does it mean that I should declare several mallocS
    > if I wanted to allocate more than 65535 bytes in a safe way?


    In theory, yes, but I generally wouldn't bother. A system with
    SIZE_MAX==65535 is unlikely to be able to allocate multiple objects
    of that size.

    SIZE_MAX is the maximum size of a single object. A system might
    limit individual objects to 65535 bytes, but allow some larger
    total amount of memory for all allocated objects. But most modern
    systems have a monolithic address space, so the maximum size of a
    single object is the same as the total available memory size.

    Unless there's some system-specific reason to do something fancier,
    I'd just try malloc()ing whatever I need and be prepared to deal with
    failure (most likely by cleaning up and terminating the program).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Oct 14, 2010
    #5
  6. Ian Collins

    Eric Sosman Guest

    On 10/14/2010 4:17 PM, Ian Collins wrote:
    > On 10/15/10 08:14 AM, Davide wrote:
    >> Hello comp.lang.c,
    >> I'm a guy from Italy. First of all, sorry for my English :)
    >> I'm attending a one-semester course in "Foundations of Programming".
    >> We use the C language and "A book on C", 4th edition, by Kelley-Pohl.
    >>
    >> At some point at the beginning of the book there is an example,
    >> the header file "pacific_sea.h". Inside this file, there is the line:
    >>
    >> #define SQ_FEET_PER_SQ_MILE (5280 * 5280)
    >>
    >> Here is my problem: the book says that writing 27878400 would be the
    >> same. This is what my teacher says too. He says that (5280 * 5280)
    >> will be automatically promoted to a type that fits that product.

    >
    > As the other replies have said, that is incorrect.
    >
    > Unless SQ_FEET_PER_SQ_MILE is required to be a compile time constant, it
    > is much clearer and less error prone to write:
    >
    > const size_t sq_feet_per_sq_mile = 5280 * 5280;


    Doesn't fix the problem: If INT_MAX < 27878400, this fragment
    has undefined behavior. Even if the result of the multiplication
    is calculated correctly, the conversion to `size_t' (which could
    be a "demotion") may change the value, quite possibly to 25600.
    Finally, `SQ_FEET_PER_SQ_MILE' can be used in some contexts where
    `sq_feet_per_sq_mile' cannot be: `case' labels, for instance (not
    a likely issue for this particular example, but let's generalize).

    --
    Eric Sosman
    lid
    Eric Sosman, Oct 15, 2010
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dead RAM
    Replies:
    20
    Views:
    1,111
    John Harrison
    Jul 14, 2004
  2. D Senthil Kumar

    macro name from macro?

    D Senthil Kumar, Sep 20, 2003, in forum: C Programming
    Replies:
    1
    Views:
    578
    Jack Klein
    Sep 21, 2003
  3. sounak

    to get macro name from macro value

    sounak, Nov 22, 2005, in forum: C Programming
    Replies:
    17
    Views:
    501
    Mark McIntyre
    Nov 22, 2005
  4. Patrick Kowalzick
    Replies:
    5
    Views:
    470
    Patrick Kowalzick
    Mar 14, 2006
  5. Mike Manilone

    macro inside macro

    Mike Manilone, Oct 3, 2011, in forum: C Programming
    Replies:
    8
    Views:
    459
    Mike Manilone
    Oct 6, 2011
Loading...

Share This Page