This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: Declaration of isspace in C/C++ not consistent?
- From: Hongxu Chen <leftcopy dot chx at gmail dot com>
- To: Mike Frysinger <vapier at gentoo dot org>
- Cc: neleai at seznam dot cz, libc-help at sourceware dot org
- Date: Mon, 17 Jun 2013 17:03:34 +0800
- Subject: Re: Declaration of isspace in C/C++ not consistent?
- References: <87ip1wvaf2 dot fsf at gmail dot com> <20130602154935 dot GA7815 at domone dot kolej dot mff dot cuni dot cz> <877gichvr0 dot fsf at gmail dot com> <201306170053 dot 12127 dot vapier at gentoo dot org>
Mike Frysinger <vapier@gentoo.org> writes:
> On Sunday 02 June 2013 20:40:35 Hongxu Chen wrote:
>> OndÅej BÃlka <neleai@seznam.cz> writes:
>> > On Sun, Jun 02, 2013 at 11:42:11PM +0800, Hongxu Chen wrote:
>> >> Mike Frysinger <vapier@gentoo.org> writes:
>> >> > On Sunday 02 June 2013 10:45:21 Hongxu Chen wrote:
>> >> >> Hi list,
>> >> >>
>> >> >> Maybe this question is a bit silly, but I just cannot understand why
>> >> >> `isspace` seems not consistent for C and C++(I have put this question
>> >> >> in stackoverflow but no satisfactory answer has been given yet).
>> >> >>
>> >> >> I am using *clang* analyzer to get the definition information and I
>> >> >> know quite little about the mechanism behind it, so the declaration
>> >> >> result might not be accurate; but I am just confused.
>> >> >>
>> >> >> For c code like this:
>> >> >> // test.c
>> >> >> #include <ctype.h>
>> >> >> int main(int argc, char *argv[]) {
>> >> >>
>> >> >> isspace('a');
>> >> >> return 0;
>> >> >>
>> >> >> }
>> >> >>
>> >> >> clang reports below as the declaration of isspace:
>> >> >> # define isspace(c) __isctype((c), _ISspace) // LINE 207 in
>> >> >>
>> >> >> /usr/include/ctype.h
>> >> >>
>> >> >> and when for this snippet:
>> >> >> // test.cpp
>> >> >> #include <cctype>
>> >> >> int main() {
>> >> >>
>> >> >> std::isspace('t');
>> >> >> return 0;
>> >> >>
>> >> >> }
>> >> >>
>> >> >> clang reports the declaration here:
>> >> >> __exctype (isspace); // LINE 120 in /usr/include/ctype.h
>> >> >> // #define __exctype(name) extern int name (int) __THROW
>> >> >>
>> >> >> So why should there be such a difference?
>> >> >
>> >> > glibc provides ctype.h which follows POSIX:
>> >> > http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/ctype.h.html
>> >> > we provide both real funcs and macros for each because the standard
>> >> > allows it, and the macro ends up producing better code at runtime.
>> >>
>> >> You mean that the c code is a macro implementation and it generates
>> >> better runtime binary while C++ code uses the function one? By saying
>> >> macro you mean `__ctype_b_loc'?(Actually I don't know what this symbol
>> >> does)
>> >>
>> >> # define __isctype(c, type) \
>> >>
>> >> ((*__ctype_b_loc ())[(int) (c)] & (unsigned short int) type)
>> >>
>> >> Also there is another implementation called `__isctype_f', which is
>> >> defined as:
>> >>
>> >> # define __isctype_f(type) \
>> >>
>> >> __extern_inline int \
>> >> is##type (int __c) __THROW \
>> >> { \
>> >>
>> >> return (*__ctype_b_loc ())[(int) (__c)] & (unsigned short int)
>> >> _IS##type; \
>> >>
>> >> }
>> >>
>> >> Then what's this supposed to be doing?
>> >
>> > Replace function call by simple table lookup where table is 1 for
>> > character inside class and 0 otherwise.
>>
>> Would you please tell some more details? You mean __isctype_f
>> implementation would actually lookup a _ISspacetype table and find
>> whether `c' is 1 in the table? Or you are talking about __isctype?
>
> __ctype_b_loc is a function call that returns the address of the data table.
> then the char is used an index into that table.
Got it, Many thanks!
> -mike
--
Regards,
Hongxu Chen