By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,563 Members | 1,023 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,563 IT Pros & Developers. It's quick & easy.

ctype & cctype in transform

P: n/a
Hi all,

A poster at http://bytes.com/forum/thread60652.html implies that using
strtoupper in transform doesn't work because ctype.h may define
strtoupper as a macro:

"The problem is that most implementations of the standard C <ctype.h>
header define functions like toupper/tolower/etc as macros. To make it
work in STL algorithms, you have to include <cctypeheader instead of
<ctype.h>. At least on my PC (Debian/gcc 3.3), <cctypeundefines all
tolower/etc macros and pulls ::tolower/::toupper/etc functions into
std namespace, so that your sample will work fine."

However, I'm quite sure the reason the call to transform fails is
because automatic type deduction fails. Is the comment made incorrect?

Also, are macro implementations allowed to be used in the C++
implementation?

Can you pass a macro in as a template parameter? eg
transform(i.begin(),i.end(),i.begin(), MY_MACRO) - maybe this would
create an anonymous function?

Thanks

Taras
Jun 27 '08 #1
Share this Question
Share on Google+
19 Replies


P: n/a
On 2008-04-24 10:15:36 -0400, Taras_96 <ta******@gmail.comsaid:
>
A poster at http://bytes.com/forum/thread60652.html implies that using
strtoupper in transform doesn't work because ctype.h may define
strtoupper as a macro:

"The problem is that most implementations of the standard C <ctype.h>
header define functions like toupper/tolower/etc as macros. To make it
work in STL algorithms, you have to include <cctypeheader instead of
<ctype.h>. At least on my PC (Debian/gcc 3.3), <cctypeundefines all
tolower/etc macros and pulls ::tolower/::toupper/etc functions into
std namespace, so that your sample will work fine."

However, I'm quite sure the reason the call to transform fails is
because automatic type deduction fails. Is the comment made incorrect?

Also, are macro implementations allowed to be used in the C++
implementation?

Can you pass a macro in as a template parameter? eg
transform(i.begin(),i.end(),i.begin(), MY_MACRO) - maybe this would
create an anonymous function?
If MY_MACRO is an object-like macro, that line would pass whatever
MY_MACRO expands to. In the case of toupper from ctype.h, if toupper is
a macro, it's a function-like macro, so it needs an argument. When
there are no arguments the macro isn't used, and the name "toupper"
refers to the underlying function.

The actual problem with using toupper, which isn't solved by using
<cctype>, is that toupper expects non-negative values (unless the value
is EOF), but the standard doesn't require that char be unsigned, so
some valid character values can be negative.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jun 27 '08 #2

P: n/a
On 2008-04-24 10:33:48 -0400, Michael DOUBEZ <mi************@free.frsaid:
>>
Can you pass a macro in as a template parameter? eg
transform(i.begin(),i.end(),i.begin(), MY_MACRO) - maybe this would
create an anonymous function?

No. MY_MACRO would be expanded.

In the case of strtoupper:
#define strtoupper(x) ((x>'a' && x<'z')?x+('A'-'a'):x)

The line:
transform(i.begin(),i.end(),i.begin(), strtoupper);
would be generated by the pre-processor as:
transform(i.begin(),i.end(),i.begin(),
((x>'a' && x<'z')?x+('A'-'a'):x)
);

Unless you can make this a lambda expression, the compiler doesn't
understand that :).
Well, yes, if the call is

transform(i.begin(), i.end(), i.begin(), toupper(x));

But

transform(i.begin(), i.end(), i.begin(), toupper);

is okay syntactically, because toupper (without any parentheses)
doesn't name the function-like macro, but names the underlying
function. The problem is that its runtime semantics are wrong if values
other than EOF in the input sequence might be negative.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jun 27 '08 #3

P: n/a
On Apr 24, 10:33 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
Taras_96 a écrit :
Hi all,
A poster athttp://bytes.com/forum/thread60652.htmlimplies that using
strtoupper in transform doesn't work because ctype.h may define
strtoupper as a macro.

Yes.
"The problem is that most implementations of the standard C <ctype.h>
header define functions like toupper/tolower/etc as macros. To make it
work in STL algorithms, you have to include <cctypeheader instead of
<ctype.h>. At least on my PC (Debian/gcc 3.3), <cctypeundefines all
tolower/etc macros and pulls ::tolower/::toupper/etc functions into
std namespace, so that your sample will work fine."

Yes
However, I'm quite sure the reason the call to transform fails is
because automatic type deduction fails. Is the comment made incorrect?

You are wrong. The preprocessing phase happens before compilation so the
macro name is never a candidate for type deduction.
Ignoring the fact that toupper might actually be a macro, what I was
suggesting that the call to transform would fail because automatic
type deduction would fail (as toupper is overloaded AND templated).
This is stated at http://lists.debian.org/debian-gcc/2.../msg00092.html.
If macro definitions of C standard functions *are* allowed in C++ (see
my comment below), it seems that you may have the *extra* problem of
toupper being a macro, so using toupper as an input to a function that
expects a function pointer may cause problems.

Does the C++ standard specify whether the standard functions are
allowed to be macro'ed in
- <name.htype libraries?
- <cnametype libraries?

The poster suggests that macro definitions are allowed in <name.h>
libraries, but not in <cnamelibraries.
>
Also, are macro implementations allowed to be used in the C++
implementation?

Macro are allowed in C++ if it is what you mean.
Where I was coming from was this statement:

"I'm not sure a conforming C++ implementation can have macro versions
of the ctype.h headers. Most versions I have seen have #ifdef __cpp__
or similar, using inline functions for the C++ version and macros for
the C one." - http://bytes.com/forum/thread60652.html (of course this
statement is not necessarily correct). If it *was* correct then the
macro expansion of toupper should never occur in a conforming standard
implementation, and thus you wouldn't have to consider the problem of
toupper actually being a macro when passing it into functions as a
function pointer (for a standard conforming implementation)

Thanks

Taras
Jun 27 '08 #4

P: n/a
On 2008-04-24 11:54:10 -0400, Taras_96 <ta******@gmail.comsaid:
>
Ignoring the fact that toupper might actually be a macro, what I was
suggesting that the call to transform would fail because automatic
type deduction would fail (as toupper is overloaded AND templated).
But it's not a template in <ctype.h>, and not in <cctype>. Of course,
each standard header in C++ implementations are allowed to pull in
names that aren't required to be defined in that header, but it would
take a rather wierd implementation to get the std::toupper from the
<localeheader when you include <cctype>.
>
Does the C++ standard specify whether the standard functions are
allowed to be macro'ed in
- <name.htype libraries?
- <cnametype libraries?

The poster suggests that macro definitions are allowed in <name.h>
libraries, but not in <cnamelibraries.
The poster is correct. The <name.hheaders are defined by the C
standard, and, with only a few exceptions (the string functions that
take const char* and return char*), their contents are the same in C++.
C allows masking macros for most functions. The <cnameheaders aren't
allowed to use masking macros, but there are a few C functions that are
defined as macros (assert, offsetof, setjmp, va_arg, va_end, va_start),
and those must be defined as macros.

>
>>
>>Also, are macro implementations allowed to be used in the C++
implementation?

Macro are allowed in C++ if it is what you mean.

Where I was coming from was this statement:

"I'm not sure a conforming C++ implementation can have macro versions
of the ctype.h headers. Most versions I have seen have #ifdef __cpp__
or similar, using inline functions for the C++ version and macros for
the C one." - http://bytes.com/forum/thread60652.html (of course this
statement is not necessarily correct). If it *was* correct then the
macro expansion of toupper should never occur in a conforming standard
implementation, and thus you wouldn't have to consider the problem of
toupper actually being a macro when passing it into functions as a
function pointer (for a standard conforming implementation)
Even if it wasn't correct, a function-like macro won't be applied if
it's not followed by a left parenthesis. So having a masking macro for
toupper doesn't matter. The second issue, and it's a genuine problem in
the original code, is that toupper expects non-negative character
values. The only negative value that's allowed is EOF. If char is
signed, the original code runs the risk of passing an illegal value to
toupper. The third issue requires more code:

#include <locale>
#include <cctype>

transform(i.begin(), i.end(), i.begin(). std::toupper);

Here, as you said, type deduction fails because there's a function and
a template, and the compiler can't make a sensible choice. And, as I
said earlier, it's theoretically possible that <ccyptealone could do
the same thing, but it's extrememly unlikely.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jun 27 '08 #5

P: n/a
On Apr 24, 10:40 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2008-04-24 10:15:36 -0400, Taras_96 <taras...@gmail.comsaid:

If MY_MACRO is an object-like macro, that line would pass whatever
MY_MACRO expands to. In the case of toupper from ctype.h, if toupper is
a macro, it's a function-like macro, so it needs an argument. When
there are no arguments the macro isn't used, and the name "toupper"
refers to the underlying function.
What underlying function are you referring to here?

Taras
Jun 27 '08 #6

P: n/a
On Apr 25, 12:52 am, Pete Becker <p...@versatilecoding.comwrote:
On 2008-04-24 11:54:10 -0400, Taras_96 <taras...@gmail.comsaid:
Ignoring the fact that toupper might actually be a macro, what I was
suggesting that the call to transform would fail because automatic
type deduction would fail (as toupper is overloaded AND templated).

But it's not a template in <ctype.h>, and not in <cctype>. Of course,
each standard header in C++ implementations are allowed to pull in
names that aren't required to be defined in that header, but it would
take a rather wierd implementation to get the std::toupper from the
<localeheader when you include <cctype>.
Does the C++ standard specify whether the standard functions are
allowed to be macro'ed in
- <name.htype libraries?
- <cnametype libraries?
The poster suggests that macro definitions are allowed in <name.h>
libraries, but not in <cnamelibraries.

The poster is correct. The <name.hheaders are defined by the C
standard, and, with only a few exceptions (the string functions that
take const char* and return char*), their contents are the same in C++.
C allows masking macros for most functions. The <cnameheaders aren't
allowed to use masking macros, but there are a few C functions that are
defined as macros (assert, offsetof, setjmp, va_arg, va_end, va_start),
and those must be defined as macros.

Thanks Pete, this is the information I was after.
>

Even if it wasn't correct, a function-like macro won't be applied if
it's not followed by a left parenthesis. So having a masking macro for
toupper doesn't matter. The second issue, and it's a genuine problem in
the original code, is that toupper expects non-negative character
values. The only negative value that's allowed is EOF. If char is
signed, the original code runs the risk of passing an illegal value to
toupper. The third issue requires more code:
For the sake of this discussion I'm ignoring that the inputs into the
functions may be negative (ie: have their upper bit set) :).

Taras
Jun 27 '08 #7

P: n/a
On Apr 24, 6:52 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2008-04-24 11:54:10 -0400, Taras_96 <taras...@gmail.comsaid:
Ignoring the fact that toupper might actually be a macro,
what I was suggesting that the call to transform would fail
because automatic type deduction would fail (as toupper is
overloaded AND templated).
But it's not a template in <ctype.h>, and not in <cctype>. Of
course, each standard header in C++ implementations are
allowed to pull in names that aren't required to be defined in
that header, but it would take a rather wierd implementation
to get the std::toupper from the <localeheader when you
include <cctype>.
It would surprise me too, but it seems to be allowed. It would
surprise me somewhat less if <algorithmpulled in <locale>,
however, and if he's going to use std::transform, he'll have
included <algorithas well.
Does the C++ standard specify whether the standard functions are
allowed to be macro'ed in
- <name.htype libraries?
- <cnametype libraries?
The poster suggests that macro definitions are allowed in
<name.hlibraries, but not in <cnamelibraries.
The poster is correct. The <name.hheaders are defined by the
C standard, and, with only a few exceptions (the string
functions that take const char* and return char*), their
contents are the same in C++. C allows masking macros for
most functions. The <cnameheaders aren't allowed to use
masking macros, but there are a few C functions that are
defined as macros (assert, offsetof, setjmp, va_arg, va_end,
va_start), and those must be defined as macros.
Where does it say that? In D.5 of the copy of the draft I have
on line, the contents of the <name.hheaders is defined (very
succinctly) in terms of the corresponding <cnameheaders, the
only difference being that the names must be visible in ::.

With regards to the original problem, I think that:

#include <ctype.h>
#include <algorithm>

std::transform( ..., ::toupper ) ;

is guaranteed to compile (and do the right thing if plain char
is unsigned).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #8

P: n/a
On Apr 25, 4:37 am, Taras_96 <taras...@gmail.comwrote:
On Apr 24, 10:40 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2008-04-24 10:15:36 -0400, Taras_96 <taras...@gmail.comsaid:
If MY_MACRO is an object-like macro, that line would pass
whatever MY_MACRO expands to. In the case of toupper from
ctype.h, if toupper is a macro, it's a function-like macro,
so it needs an argument. When there are no arguments the
macro isn't used, and the name "toupper" refers to the
underlying function.
What underlying function are you referring to here?
The C standard allows toupper to be defined as a function style
macro, but it requires a toupper function, even if there is also
a macro. An implementation providing the macro must do
something like:
extern int toupper( int ) ;
#define toupper( ch ) ...
If you use the symbol toupper in a context where it is not
immediately followed by an opening parentheses, the macro is not
expanded, and you get the function, e.g.

int (*pf)( int ) = toupper ;
// or even
int ch = (toupper)( ch ) ;

(The implementation probably uses this trick itself, e.g.:

// toupper.c
#include <ctype.h>

int
(toupper)( int ch )
{
return toupper( ch ) ;
}

.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #9

P: n/a
On 2008-04-24 22:37:35 -0400, Taras_96 <ta******@gmail.comsaid:
On Apr 24, 10:40 pm, Pete Becker <p...@versatilecoding.comwrote:
>On 2008-04-24 10:15:36 -0400, Taras_96 <taras...@gmail.comsaid:

If MY_MACRO is an object-like macro, that line would pass whatever
MY_MACRO expands to. In the case of toupper from ctype.h, if toupper is
a macro, it's a function-like macro, so it needs an argument. When
there are no arguments the macro isn't used, and the name "toupper"
refers to the underlying function.

What underlying function are you referring to here?
toupper. There are a few things that C requires to be macros; in all
other cases, there must be a function, even if it's masked by a macro
with the same name.

#include <ctype.h>
#undef toupper
toupper('a');

This is always required to be legal, even if <ctype.hprovides a macro
named toupper.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jun 27 '08 #10

P: n/a
On 2008-04-25 03:04:10 -0400, Michael DOUBEZ <mi************@free.frsaid:
Pete Becker a écrit :
>On 2008-04-24 10:33:48 -0400, Michael DOUBEZ <mi************@free.frsaid:
>>#define strtoupper(x) ((x>'a' && x<'z')?x+('A'-'a'):x)

The line:
transform(i.begin(),i.end(),i.begin(), strtoupper);
would be generated by the pre-processor as:
transform(i.begin(),i.end(),i.begin(),
((x>'a' && x<'z')?x+('A'-'a'):x)
);

Unless you can make this a lambda expression, the compiler doesn't
understand that :).

Well, yes, if the call is

transform(i.begin(), i.end(), i.begin(), toupper(x));

But

transform(i.begin(), i.end(), i.begin(), toupper);

is okay syntactically, because toupper (without any parentheses)
doesn't name the function-like macro, but names the underlying
function. The problem is that its runtime semantics are wrong if values
other than EOF in the input sequence might be negative.

Yes, silly of me.
But the problem would be the same. The preprocessing phase is before
the compilation phase so transform(,,,toupper), even when
expanded/matched with the template, wouldn't be able to use the macro.
See my earlier message, listing all three issues. This discussion gets
muddled easily.
>
If there is a function of the same name, then yes, it would match it
but this function would conflict with the #define in the header because
the declaration would be expanded with the macro (hence the #undef in
<cctypeI guess).
No, that's the point: if toupper is not expanded as a macro, then it's
the name of the function. There's no conflict.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jun 27 '08 #11

P: n/a
On 2008-04-25 05:29:29 -0400, James Kanze <ja*********@gmail.comsaid:
On Apr 24, 6:52 pm, Pete Becker <p...@versatilecoding.comwrote:
>The poster is correct. The <name.hheaders are defined by the
C standard, and, with only a few exceptions (the string
functions that take const char* and return char*), their
contents are the same in C++. C allows masking macros for
most functions. The <cnameheaders aren't allowed to use
masking macros, but there are a few C functions that are
defined as macros (assert, offsetof, setjmp, va_arg, va_end,
va_start), and those must be defined as macros.

Where does it say that? In D.5 of the copy of the draft I have
on line, the contents of the <name.hheaders is defined (very
succinctly) in terms of the corresponding <cnameheaders, the
only difference being that the names must be visible in ::.
17.4.1.2 [headers]/6: "Names that are defined as functions in C shall be
defined as functions in the C++ Standard Library.*" The "*" points to a
footnote: "This disallows the practice, allowed in C, of providing a
"masking macro" in addition to the function prototype. The only way to
achieve
equivalent "inline" behavior in C++ is to provide a definition as an
extern inline function. "

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jun 27 '08 #12

P: n/a
On 2008-04-25 05:34:54 -0400, James Kanze <ja*********@gmail.comsaid:
>
The C standard allows toupper to be defined as a function style
macro, but it requires a toupper function, even if there is also
a macro. An implementation providing the macro must do
something like:
extern int toupper( int ) ;
#define toupper( ch ) ...
If you use the symbol toupper in a context where it is not
immediately followed by an opening parentheses, the macro is not
expanded, and you get the function, e.g.
"Immediately followed by" is a bit too strong; you can have whitespace
between them. You get the function if the first non-whitespace
character after the name is not an opening parenthesis.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jun 27 '08 #13

P: n/a
On Apr 25, 1:31 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2008-04-25 05:29:29 -0400, James Kanze <james.ka...@gmail.comsaid:
On Apr 24, 6:52 pm, Pete Becker <p...@versatilecoding.comwrote:
The poster is correct. The <name.hheaders are defined by the
C standard, and, with only a few exceptions (the string
functions that take const char* and return char*), their
contents are the same in C++. C allows masking macros for
most functions. The <cnameheaders aren't allowed to use
masking macros, but there are a few C functions that are
defined as macros (assert, offsetof, setjmp, va_arg, va_end,
va_start), and those must be defined as macros.
Where does it say that? In D.5 of the copy of the draft I have
on line, the contents of the <name.hheaders is defined (very
succinctly) in terms of the corresponding <cnameheaders, the
only difference being that the names must be visible in ::.
17.4.1.2 [headers]/6: "Names that are de?ned as functions in C
shall be de?ned as functions in the C++ Standard Library.*"
The "*" points to a footnote: "This disallows the practice,
allowed in C, of providing a "masking macro" in addition to
the function prototype. The only way to achieve equivalent
"inline" behavior in C++ is to provide a de?nition as an
extern inline function. "
I don't think I was clear. That part I knew. I interpreted
your posting as saying that the <name.hheaders could define
the macros, even in C++, and I was wondering where you'd read
that. On rereading what you said, however, I don't think you
actually said that, so the question is irrelevant.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #14

P: n/a
On Apr 25, 1:37 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2008-04-25 05:34:54 -0400, James Kanze <james.ka...@gmail.comsaid:
The C standard allows toupper to be defined as a function style
macro, but it requires a toupper function, even if there is also
a macro. An implementation providing the macro must do
something like:
extern int toupper( int ) ;
#define toupper( ch ) ...
If you use the symbol toupper in a context where it is not
immediately followed by an opening parentheses, the macro is not
expanded, and you get the function, e.g.
"Immediately followed by" is a bit too strong; you can have
whitespace between them. You get the function if the first
non-whitespace character after the name is not an opening
parenthesis.
Yes. What I meant by "immediately" were the tokens, not the
text. (Thinking too much in terms of compiler writing:-).)

I wonder: is this before or after other expansions. In other
words, given something like:

#define TOTO
// ...
toupper TOTO (...)

am I guaranteed to get the function or not?

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #15

P: n/a
On 2008-04-25 11:51:55 -0400, James Kanze <ja*********@gmail.comsaid:
>
Yes. What I meant by "immediately" were the tokens, not the
text. (Thinking too much in terms of compiler writing:-).)
<g>
>
I wonder: is this before or after other expansions. In other
words, given something like:

#define TOTO
// ...
toupper TOTO (...)

am I guaranteed to get the function or not?
I think so. Formally, if the next preprocessing-token is not a (, it's
not a macro invocation. TOTO is an identifier, hence a
preprocessing-token, so I think you get the function.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jun 27 '08 #16

P: n/a
On Apr 25, 5:29 pm, James Kanze <james.ka...@gmail.comwrote:
On Apr 24, 6:52 pm, Pete Becker <p...@versatilecoding.comwrote:
>
Where does it say that? In D.5 of the copy of the draft I have
on line, the contents of the <name.hheaders is defined (very
succinctly) in terms of the corresponding <cnameheaders, the
only difference being that the names must be visible in ::.

With regards to the original problem, I think that:

#include <ctype.h>
#include <algorithm>

std::transform( ..., ::toupper ) ;

is guaranteed to compile (and do the right thing if plain char
is unsigned).

--
Sorry for the newb question, but what is the ::function_name syntax?

Taras
Jun 27 '08 #17

P: n/a
On Apr 28, 5:10 am, Taras_96 <taras...@gmail.comwrote:
On Apr 25, 5:29 pm, James Kanze <james.ka...@gmail.comwrote:
On Apr 24, 6:52 pm, Pete Becker <p...@versatilecoding.comwrote:
Where does it say that? In D.5 of the copy of the draft I have
on line, the contents of the <name.hheaders is defined (very
succinctly) in terms of the corresponding <cnameheaders, the
only difference being that the names must be visible in ::.
With regards to the original problem, I think that:
#include <ctype.h>
#include <algorithm>
std::transform( ..., ::toupper ) ;
is guaranteed to compile (and do the right thing if plain char
is unsigned).
Sorry for the newb question, but what is the ::function_name syntax?
The :: operator is scope resolution operator. It is used to
tell the compiler where to look for the symbol (any symbol, not
just a function name); as a unary operator (as it is here), it
specifies that the symbol should be looked up in global scope
(and only in global scope). Thus, symbols in the std namespace
will not be found (and if you write std::toupper, symbols in the
global namespace will not be found).

If I understand the current draft correctly, symbols (except
macros) defined in <ctype.hwill be defined in the global
namespace (and maybe in std as well); symbols defined in
<cctypewill be defined in the std namespace, and maybe in ::
as well.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #18

P: n/a
On Apr 25, 6:52 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2008-04-25 11:51:55 -0400, James Kanze <james.ka...@gmail.comsaid:
[...]
I wonder: is this before or after other expansions. In other
words, given something like:
#define TOTO
// ...
toupper TOTO (...)
am I guaranteed to get the function or not?
I think so. Formally, if the next preprocessing-token is not a
(, it's not a macro invocation. TOTO is an identifier, hence a
preprocessing-token, so I think you get the function.
That's what I think the standard requires, but I'm quite sure
about the implications of [cpp.rescan] if the text in question
is itself in a macro. If I interpret it correctly, the
replacement list is only rescanned once, after replacement of
the parameters (but not other macros), to I'd still be
guaranteed to get the function. But if the text is rescanned
after TOTO has been expanded, then suddenly toupper becomes a
macro again.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #19

P: n/a
On Apr 28, 5:37 pm, James Kanze <james.ka...@gmail.comwrote:
On Apr 28, 5:10 am, Taras_96 <taras...@gmail.comwrote:
On Apr 25, 5:29 pm, James Kanze <james.ka...@gmail.comwrote:
On Apr 24, 6:52 pm, Pete Becker <p...@versatilecoding.comwrote:
Where does it say that? In D.5 of the copy of the draft I have
on line, the contents of the <name.hheaders is defined (very
succinctly) in terms of the corresponding <cnameheaders, the
only difference being that the names must be visible in ::.
With regards to the original problem, I think that:
#include <ctype.h>
#include <algorithm>
std::transform( ..., ::toupper ) ;
is guaranteed to compile (and do the right thing if plain char
is unsigned).
Sorry for the newb question, but what is the ::function_name syntax?

The :: operator is scope resolution operator. It is used to
tell the compiler where to look for the symbol (any symbol, not
just a function name); as a unary operator (as it is here), it
specifies that the symbol should be looked up in global scope
(and only in global scope). Thus, symbols in the std namespace
will not be found (and if you write std::toupper, symbols in the
global namespace will not be found).
Ok - makes sense :)

Jun 27 '08 #20

This discussion thread is closed

Replies have been disabled for this discussion.