Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C vs C++ compilation incompatibility - does not name a type

Tags:

c++

c

gcc

g++

I am trying to use a supplier's library in combination with my C++ application. The library is largely based on C, which is normally not a problem with the extern "C" option, but I ran into an issue that the C++ compiler does not accept.

I simplified my code into the following example files. header.h represents a header from the suppier library, main.c/cpp are my own files. My real application is a C++ application, so I want to get it to work with main.cpp.

header.h (note the line u64 u64;):

#ifndef HEADER_H #define HEADER_H  #include <stdint.h>  typedef uint64_t u64;  union teststruct {     u64 u64;     struct {         u64 x:32;         u64 y:32;     } s; };  #endif 

main.c:

#include <stdio.h> #include "header.h"  int main() {     union teststruct a;     a.u64=5;     printf("%x\n", a.u64);      return 0; } 

main.cpp (same as main.c but with an extra extern "C" statement):

#include <stdio.h>  extern "C" { #include "header.h" }  int main() {     union teststruct a;     a.u64=5;     printf("%x\n", a.u64);      return 0; } 

Compiling main.c using the line

gcc -o test main.c 

compiles without problems. However, compiling the C++ version using the g++ compiler with the command

g++ -o test main.cpp 

gives the following compiler errors:

In file included from main.cpp:12:0: header.h:11:9: error: ‘u64’ does not name a type          u64 x:32;          ^ header.h:12:9: error: ‘u64’ does not name a type          u64 y:32;          ^ 

The issue is that the supplier used the same name (u64) for both the type and the variable name, which seems like a bad idea to begin with, but gcc apparently accepts it. I do not want to change the library (i.e. header.h) as it is very large,this occurs a lot in the code, and I occasionally get updates for it. Is there a way to make g++ accept this combination, or a way to modify main.cpp to make it compile without changing header.h?

like image 316
Sander Avatar asked Jun 27 '18 11:06

Sander


People also ask

What does the error does not name a type mean?

The "error does not name a type" in C/C++ is defined as the when user declares outside of the function or does not include it properly in the main file this error will through.

How is C++ incompatible with C?

Constructs valid in C but not in C++ C++ enforces stricter typing rules (no implicit violations of the static type system), and initialization requirements (compile-time enforcement that in-scope variables do not have initialization subverted) than C, and so some valid C code is invalid in C++.

How do you name a type in C++?

C++ code. Use CamelCase for all names. Start types (such as classes, structs, and typedefs) with a capital letter, other names (functions, variables) with a lowercase letter.


2 Answers

teststruct defines a scope in C++. You can form the qualified id teststruct::u64. So the language rules for name lookup account for that, allowing members of classes and unions to hide identifiers in outer scope. Once u64 u64; is introduced, the unqualified u64 cannot refer to the global ::u64, only the member. And the member is not a type.

In C union teststruct does not define a scope. The field can only be used in member access, so there can never arise a conflict. As such the field need not hide the file scope type identifier.

There is nothing, as far as I can tell, that you may do in order to easily work around it. This library (which is a perfectly valid C library), is not a valid C++ library. No different than if it used new or try as variable names. It needs to be adapted.

like image 121
StoryTeller - Unslander Monica Avatar answered Oct 12 '22 22:10

StoryTeller - Unslander Monica


It seems that you have a header file that is illegal in C++, so you cannot #include it in code compiled as C++. If you cannot effect a change in the library header file (e.g. by complaining to your library supplier) then the most straightforward option is to write a thin C++-compatible wrapper around the library:

To isolate your C++ code against the C header, create a Wrapper.h and Wrapper.c, where the .h is valid for inclusion in C++, does not include header.h, and provides all types and functions that you need for library interaction. Then, in the .c, you can #include "header.h" and implement all the calls (and whatever you need to do to safely convert between the types). This would obviously have to be compiled as C, not C++.

like image 34
Max Langhof Avatar answered Oct 12 '22 21:10

Max Langhof