Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Testing C include file for C++ compatibility without a C++ caller?

Reply
Thread Tools

Testing C include file for C++ compatibility without a C++ caller?

 
 
mathog
Guest
Posts: n/a
 
      10-17-2013
I have a C package that until recently was callable by C++ programs
without generating warnings. Everything is properly wrapped up in

#ifdef __cplusplus
extern "C" {
#endif

which I always assumed precluded the possibility of a cleanly compiling
C module throwing warnings and errors when compiled by a C++ compiler.
However, recent versions of g++ throw warnings like this when some C++
modules include AND use one of the include files in the package:

.../../src/extension/internal/metafile-print.cpp:132:13: warning:
narrowing conversion of ‘((color >> 16) & 255u)’ from ‘uint32_t
{aka unsigned int}’ to ‘uint8_t {aka unsigned char}’ inside { } is
ill-formed in C++11 [-Wnarrowing]

These trace back to this line in the include file:

#define U_RGBA(r,g,b,a) (U_COLORREF){r,g,b,a}

which must be changed to this to eliminate the warning:

#define U_RGBA(r,g,b,a)
(U_COLORREF){(uint8_t)(r), (uint8_t)(g), (uint8_t)(b), (uint8_t)(a)}

Where U_COLORREF is defined earlier in that include file as:

typedef struct {
uint8_t Red; //!< Red color (0-255)
uint8_t Green; //!< Green color (0-255)
uint8_t Blue; //!< Blue color (0-255)
uint8_t Reserved; //!< Not used
} U_COLORREF, *PU_COLORREF;

The problem is that so far the warning only shows up when the U_RGBA is
actually USED in a C++ module, apparently with a 4 byte unsigned
(holding a value in the range 0-255) employed as one of the color values.

I have the c++ compiler line that when applied to the cpp file generates
the error message, but when run exactly the same way, but just on the
include file, like:

g++ .... -c include.h

there are no warnings.

Is it possible to test for this sort of issue using just the C++
compiler and the include file? (Using gcc or g++).

Thank you,

David Mathog
 
Reply With Quote
 
 
 
 
Tiib
Guest
Posts: n/a
 
      10-17-2013
On Thursday, 17 October 2013 20:09:54 UTC+3, mathog wrote:
> I have the c++ compiler line that when applied to the cpp file generates
> the error message, but when run exactly the same way, but just on the
> include file, like:
>
> g++ .... -c include.h
>
> there are no warnings.


Default behavior of that compiler with .h files is AFAIK to turn those
into precompiled headers (e.g. -x c++-header). If you want to preprocess
and compile .h file like c++ source file then use something like:

gcc -x c++ include.h

 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      10-17-2013
On 17.10.2013 19:09, mathog wrote:
> I have a C package that until recently was callable by C++ programs
> without generating warnings. Everything is properly wrapped up in
>
> #ifdef __cplusplus
> extern "C" {
> #endif
>
> which I always assumed precluded the possibility of a cleanly compiling
> C module throwing warnings and errors when compiled by a C++ compiler.
> However, recent versions of g++ throw warnings like this when some C++
> modules include AND use one of the include files in the package:
>
> ../../src/extension/internal/metafile-print.cpp:132:13: warning:
> narrowing conversion of ‘((color >> 16) & 255u)’ from ‘uint32_t
> {aka unsigned int}’ to ‘uint8_t {aka unsigned char}’ inside { } is
> ill-formed in C++11 [-Wnarrowing]
>
> These trace back to this line in the include file:
>
> #define U_RGBA(r,g,b,a) (U_COLORREF){r,g,b,a}
>
> which must be changed to this to eliminate the warning:
>
> #define U_RGBA(r,g,b,a)
> (U_COLORREF){(uint8_t)(r), (uint8_t)(g), (uint8_t)(b), (uint8_t)(a)}
>
> Where U_COLORREF is defined earlier in that include file as:
>
> typedef struct {
> uint8_t Red; //!< Red color (0-255)
> uint8_t Green; //!< Green color (0-255)
> uint8_t Blue; //!< Blue color (0-255)
> uint8_t Reserved; //!< Not used
> } U_COLORREF, *PU_COLORREF;
>
> The problem is that so far the warning only shows up when the U_RGBA is
> actually USED in a C++ module, apparently with a 4 byte unsigned
> (holding a value in the range 0-255) employed as one of the color values.


The U_RGBA macro would not work for a standard-compliant C++03 compiler.

It uses a C99 feature for which there is a syntactically similar C++11
feature, which incidentally gives almost the same effect...

The expression

(U_COLORREF){ 1, 2, 3 }

is a C99 *compound literal*, as defined by C99 6.5.2.5. Constraints on
the values are given by 7th para "All the semantic rules and constraints
for initializer lists in 6.7.8 are applicable to compound literals".
And when you go there you there you find in its 11th para that "The
initializer for a scalar shall be a single expression, optionally
enclosed in braces. The initial value of the object is that of the
expression (after conversion); the same type constraints and conversions
as for simple assignment apply", which means that any numeric conversion
is accepted -- in C99.

For C99 the parenthesis is part of the compound literal syntax and
cannot be omitted. In C++11 the parenthesis is ignored other than as a
logical grouping, yielding the expression

U_COLORREF{ 1, 2, 3 }

which syntactically, in C++11, is an *explicit type conversion* using
*functional notation*, as specified by C++11 5.2.3. And in the 3rd
paragraph there you find that this specific form (which was introduced
in C++11, not available in C++03) is a **list initialization**. It
simply creates a temporary object with the given values or with those
values passed as constructor arguments, depending on the type.

In this case it's a list initialization of a C++ **aggregate** (because
U_COLORREF is an aggregate), and C++11 8.5.1/2 then tells you -- as
did the g++ warning message -- that "If the initializer-clause is an
expression and a narrowing conversion (8.5.4) is required to convert the
expression, the program is ill-formed". That is, it's *ILL-FORMED*,
invalid, not correct, it shouldn't really compile but g++ is lenient.

So, the upshot is that you don't really want that thing.

It has different meanings in C and C++, won't compile with C++03
compiler, and shouldn't really compile with a C++11 compiler.

A general solution is to use a value factory function, and rely on
(common but not formally guaranteed) machine code inlining to avoid the
call overhead.

An alternative in this particular case is to use a 32-bit integer with
packing and unpacking macros, but it's not as type safe.


> I have the c++ compiler line that when applied to the cpp file generates
> the error message, but when run exactly the same way, but just on the
> include file, like:
>
> g++ .... -c include.h
>
> there are no warnings.


The macro is not invoked.


> Is it possible to test for this sort of issue using just the C++
> compiler and the include file? (Using gcc or g++).


No, you need an invocation.

The invalid code for C++11 is the invocation, not the definition.


Cheers & hth.,

- Alf

 
Reply With Quote
 
mathog
Guest
Posts: n/a
 
      10-17-2013
Alf P. Steinbach wrote:
>
> The U_RGBA macro would not work for a standard-compliant C++03 compiler.


....

> So, the upshot is that you don't really want that thing.


Interesting.

I will convert them to function calls which should eliminate the problem.

Thanks,

David Mathog
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Regression testing for HTTP server Jim Janney Java 5 05-17-2013 06:17 PM
Include and lib files for Visual Studio? xucaen@gmail.com Python 3 04-21-2013 01:04 AM
API design for Python 2 / 3 compatibility Stefan Schwarzer Python 3 04-14-2013 11:11 AM
/* #include <someyhing.h> */ => include it or do not include it?That is the question .... Andreas Bogenberger C Programming 3 02-22-2008 10:53 AM
Can't get function caller if the caller is from a function within a popup window Mark Javascript 2 04-03-2004 07:57 AM



Advertisments