Functions implemented as macros?

Discussion in 'C Programming' started by Pedro Graca, Jan 19, 2008.

  1. Pedro Graca

    Pedro Graca Guest

    I wrote a pair of functions to make a string all uppercase or
    lowercase.
    The functions call a helper static function to do the conversion
    including the address of toupper() or tolower() in the parameters.

    My questions is:
    Does the Standard allow toupper() or tolower() to be implemented as a
    macro?
    (Unlike for getc(), my documentation doesn't say they can be
    implemented as macros)

    To be on the safe side, should I add

    #ifdef tolower
    /* alternate version */
    #else
    /* my version */
    #endif

    -----------------------------------------------

    This is the code I have:

    #include <ctype.h>
    #include <stddef.h>

    static char *chg_str(char *destin, char *source, size_t n, int(f)
    (int)) {
    char *d = destin;
    while (--n && *source) {
    *destin = f(*source);
    ++source;
    ++destin;
    }
    *destin = 0;
    return d;
    }

    char *lo_str(char *destin, char *source, size_t n) {
    if (!source || !destin) return NULL;
    if (!n) return destin;
    return chg_str(destin, source, n, tolower);
    }
     
    Pedro Graca, Jan 19, 2008
    #1
    1. Advertising

  2. Pedro Graca

    James Kuyper Guest

    Pedro Graca wrote:
    > I wrote a pair of functions to make a string all uppercase or
    > lowercase.
    > The functions call a helper static function to do the conversion
    > including the address of toupper() or tolower() in the parameters.
    >
    > My questions is:
    > Does the Standard allow toupper() or tolower() to be implemented as a
    > macro?


    Yes, that permission applies to all standard library functions, unless
    it is specifically stated otherwise for a specific function. I found no
    contrary statement in any of the obvious places for toupper() and tolower().

    ....
    > To be on the safe side, should I add
    >
    > #ifdef tolower
    > /* alternate version */
    > #else
    > /* my version */
    > #endif


    You don't need to get that complicated. As long as the function name is
    not immediately followed by a '(' preprocessing token, it cannot be
    treated as the invocation of a function-like macro; it has to be treated
    as the name of the function. It will therefore decay into a pointer to
    that function in most contexts, including:

    > return chg_str(destin, source, n, tolower);
     
    James Kuyper, Jan 19, 2008
    #2
    1. Advertising

  3. Pedro Graca

    Army1987 Guest

    Pedro Graca wrote:

    > I wrote a pair of functions to make a string all uppercase or
    > lowercase.
    > The functions call a helper static function to do the conversion
    > including the address of toupper() or tolower() in the parameters.
    >
    > My questions is:
    > Does the Standard allow toupper() or tolower() to be implemented as a
    > macro?

    Any function is allowed to be implemented as a macro, provided that it has
    the same semantics of the function (except for getc/putc, and except for
    sequence points), and that there is also a real function with that name.

    > To be on the safe side, should I add
    >
    > #ifdef tolower
    > /* alternate version */
    > #else
    > /* my version */
    > #endif

    [snip]
    > char *lo_str(char *destin, char *source, size_t n) {
    > if (!source || !destin) return NULL;
    > if (!n) return destin;
    > return chg_str(destin, source, n, tolower);

    When the identifier for a function-like macro isn't immediately followed
    by the `(` token, it doesn't get replaced. So that tolower stays tolower,
    which evaluates to the address of the extern function, regardless of
    whether there is a macro with that same name. So you can be safe.
    > }




    --
    Army1987 (Replace "NOSPAM" with "email")
     
    Army1987, Jan 19, 2008
    #3
  4. Pedro Graca

    Pedro Graca Guest

    Army1987 wrote:
    > Pedro Graca wrote:
    > >
    > > My questions is:
    > > Does the Standard allow toupper() or tolower() to be implemented as a
    > > macro?

    > Any function is allowed to be implemented as a macro, provided [...]
    > that there is also a real function with that name.


    Ah! Thank you :)
     
    Pedro Graca, Jan 19, 2008
    #4
  5. Pedro Graca

    pete Guest

    James Kuyper wrote:
    >
    > Pedro Graca wrote:


    > > My questions is:
    > > Does the Standard allow toupper() or tolower()
    > > to be implemented as a macro?

    >
    > Yes, that permission applies to all standard library functions, unless
    > it is specifically stated otherwise for a specific function.


    Is it specifically stated otherwise
    for any standard library functions?

    I'm unaware of any exceptions.

    --
    pete
     
    pete, Jan 19, 2008
    #5
  6. Pedro Graca

    James Kuyper Guest

    pete wrote:
    > James Kuyper wrote:
    >> Pedro Graca wrote:

    >
    >>> My questions is:
    >>> Does the Standard allow toupper() or tolower()
    >>> to be implemented as a macro?

    >> Yes, that permission applies to all standard library functions, unless
    >> it is specifically stated otherwise for a specific function.

    >
    > Is it specifically stated otherwise
    > for any standard library functions?


    I was trying to mirror the wording from 7.1.4p1: "Each of the following
    statements applies unless explicitly stated otherwise in the detailed
    descriptions that follow: ... Any function declared in a header may be
    additionally implemented as a function-like macro defined in the header,
    ....".

    > I'm unaware of any exceptions.


    There's several cases where a standard library feature is explicitly
    described as being only a function-like macro, and not a function.
    However, I couldn't find any examples of the reverse case: functions
    where implementation as a macro was prohibited. 7.1.4p1 permits
    exceptions, but there don't seem to be any.
     
    James Kuyper, Jan 20, 2008
    #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. Replies:
    80
    Views:
    2,458
    Stephen J. Bevan
    Nov 7, 2003
  2. Replies:
    1
    Views:
    465
    Marco Antoniotti
    Oct 7, 2003
  3. Replies:
    5
    Views:
    507
  4. Michael T. Babcock

    Re: Explanation of macros; Haskell macros

    Michael T. Babcock, Nov 3, 2003, in forum: Python
    Replies:
    0
    Views:
    531
    Michael T. Babcock
    Nov 3, 2003
  5. Immortal Nephi
    Replies:
    0
    Views:
    413
    Immortal Nephi
    Feb 27, 2010
Loading...

Share This Page