Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ reserved symbol as C variable name

Tags:

c++

c

I'm using an external C library inside a C++ project.

The header contains a struct with a variable named class:

#ifdef __cplusplus
extern "C" {
#endif

struct something_t {
    ...
    sometype class;
};


#ifdef __cplusplus
}
#endif

g++ does not like this and complains about "error: expected identifier before ';' token".

What options do I have?

  1. I could rename class, but that's cumbersome and breaks upstream compatibility.
  2. I could ask the upstream project to rename the variable, but that may be difficult.
  3. I could redefine class in the header using the preprocessor: #define class class_ Are there any side effects?
  4. Any other suggestions?

What's the best way to handle this situation?

Result: Based on the prevailing preference for option 2, I finally chose to initiate a renaming in the upstream library.

like image 798
Tim Hoffmann Avatar asked Oct 15 '17 09:10

Tim Hoffmann


People also ask

Which is a correct variable naming for C?

Variable names in C are made up of letters (upper and lower case) and digits. The underscore character ("_") is also permitted. Names must not begin with a digit. Unlike some languages (such as Perl and some BASIC dialects), C does not use any special prefix characters on variable names.

Can you use symbols in variable name?

The $ sign is not allowed as the initial character of a user-defined variable. The period, the underscore, and the characters $, #, and @ can be used within variable names. For example, A. _$@#1 is a valid variable name.

What characters are allowed in C variable names?

Rules for naming a variable A variable name can only have letters (both uppercase and lowercase letters), digits and underscore. The first letter of a variable should be either a letter or an underscore. There is no rule on how long a variable name (identifier) can be.

Can special characters be used in variable in C?

The C rule of declaring variable name says that variable name starts with the underscore but not with other special characters, and it should not be any identifier name.


1 Answers

As others already mentioned in comments, the best option is to write another C API layer around that stuff, that uses the other API only internally.

Anything related to this offending struct definition should be exported through opaque pointers only.

In C++ you can use the cleaned up C-API then.


Here's a small sketch:

ThirdParty.h (contains offending code to compile with c++)

#ifdef __cplusplus
extern "C" {
#endif

struct something_t {
    ...
    sometype class;
};

struct something_t* CreateSomething(); // Does memory allocation and initialization
void DoSomething(struct something_t* something);

#ifdef __cplusplus
}
#endif

MyApiWrapper.h

#ifdef __cplusplus
extern "C" {
#endif

typedef void* psomething_t;

struct psomething_t MyCreateSomething(); // Does memory allocation and initialization
void MyDoSomething(psomething_t something);

#ifdef __cplusplus
}
#endif

MyApiWrapper.c

#include "ThirdParty.h"

struct psomething_t MyCreateSomething() {
     psomething_t psomething = (psomething_t)CreateSomething();
     return psomething;
}

void MyDoSomething(psomething_t something) {
    DoSomething((struct something_t*)psomething);
}

Regarding your considered solutions

  1. I could ask the upstream project to rename the variable, but that may be difficult

You certainly should report that bug to let them know. If it's a git-hub hosted project prepare a pull request.

Anyways be prepared that they might not be responsive timely, and you should always have the above mentioned "plan B". It will work regardless ...

  1. I could redefine class in the header using the preprocessor: #define class class_ Are there any side effects?

It could be a viable way, if any place where this particular symbol (class) appears is plain c code and no other parts of the 3rd party c code (e.g. as library) depends on that symbol (which is unlikely).

like image 107
user0042 Avatar answered Sep 18 '22 08:09

user0042