Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redefinition error in system header file because of "signed char" and "char"

Tags:

c++

linux

I try to include this file

 boost/assign/list_of.hpp

but i have this compiler's error

/usr/include/boost/type_traits/is_integral.hpp:38: error: redefinition of struct boost::is_integral<char>
/usr/include/boost/type_traits/is_integral.hpp:32: error: previous  definition of  struct boost::is_integral<char>

these definitions lines (32,38) in file is_integral.hpp are:

BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,signed char,true)
BOOST_TT_AUX_BOOL_TRAIT_CV_SPEC1(is_integral,char,true)

how to solve compile problem? the compiler is gcc version 4.4.7 20120313 OS is Red Hat Enterprise Linux Server release 6.5 (Santiago)

like image 649
dt128 Avatar asked Oct 30 '22 14:10

dt128


1 Answers

From C++ standard

3.9.1 Fundamental types [basic.fundamental]

Objects declared as characters (char) shall be large enough to store any member of the implementation's basic character set. If a character from this set is stored in a character object, the integral value of that character object is equal to the value of the single character literal form of that character. It is implementation-defined whether a char object can hold negative values. Characters can be explicitly declared unsigned or signed. Plain char, signed char, and unsigned char are three distinct types. A char, a signed char, and an unsigned char occupy the same amount of storage and have the same alignment requirements (basic.types); that is, they have the same object representation. For character types, all bits of the object representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types. In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.

char, unsigned char and signed char are thus three distinct types and boost::is_integral should be specializable for those three types. One can expect gcc 4.4.7 or OP's environment to ignore that and I'll be looking for an explanation. Please see this temporary answer as an extended comment on OP's question.


EDIT: Cannot reproduce

System: Red Hat 6

$ uname -a
Linux ysc 2.6.32-504.8.1.el6.x86_64 #1 SMP Wed Jan 28 21:11:36 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux$

Compiler:

$ g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)

Source:

$ cat main.cpp

#include <iostream>

template<typename T>
struct trait
{
    static const int value = 0;
};

template<>
struct trait<char>
{
    static const int value = 1;
};

template<>
struct trait<signed char>
{
    static const int value = 2;
};

template<>
struct trait<unsigned char>
{
    static const int value = 3;
};

int main()
{
  std::cout << "int:, " << trait<int>::value << "!\n";
  std::cout << "char:, " << trait<char>::value << "!\n";
  std::cout << "unsigned char:, " << trait<unsigned char>::value << "!\n";
  std::cout << "signed char:, " << trait<signed char>::value << "!\n"; 
}

Compilation:

$ g++ -Wall -Wextra main.cpp 

Run:

$ ./a.out 
int:, 0!
char:, 1!
unsigned char:, 3!
signed char:, 2!

What does it produce on OP's environment?

like image 176
YSC Avatar answered Nov 02 '22 11:11

YSC