11

I am having trouble writing C++ code that uses a header file designed for a C file. In particular, the header file used a variable name called class:

int BPY_class_validate(const char *class_type, PyObject *class, PyObject *base_class, BPY_class_attr_check* class_attrs, PyObject **py_class_attrs);

This works in C as class isn't taken as a keyword, but in C++, class is. So is there anyway I can #include this header file into a c++ file, or am I out of luck?

Thank you.

Leif Andersen
  • 21,580
  • 20
  • 67
  • 100
  • If that code isn't prepared for being parsed by a C++ compiler, be prepared for more trouble. For example, if this is a C lib you want to link against, all declarations should be wrapped in `extern "C"` so that the linker knows it needs to look for unmangled symbols. – sbi May 15 '10 at 18:24
  • The compiler still throws a fit when I just wrap the #include in an extern "C". Should I include aaa's trick inside of yours? – Leif Andersen May 15 '10 at 18:48
  • I just realized this is a Python header. I have no idea which header you're using and what it is used for, but do you know http://www.boost.org/doc/libs/1_43_0/libs/python/doc/index.html? – sbi May 17 '10 at 21:19

5 Answers5

11

try something like this:

#define class class_variable
// if class is only used in declarations, you can also do
// #define class
#include "c.h"
#undef class

it may cause problems, but maybe worth a shot

alternative (using Makefile):

python_.hpp: /usr/include/python.h
    perl -pe 's/\Wclass\W//g' $< > $@
...

#include "python_.hpp"
Anycorn
  • 50,217
  • 42
  • 167
  • 261
  • It worked...although I haven't linked the libraries yet, thank you though. – Leif Andersen May 15 '10 at 18:20
  • @Leif good luck. May also want to manually inspect preprocessed file just make sure there were not any unwanted side effects introduced – Anycorn May 15 '10 at 18:21
  • 1
    If you use any of the standard library headers, defining a macro with a keyword as its name is not permitted (cf. http://stackoverflow.com/questions/2726204/c-preprocessor-define-ing-a-keyword-is-it-standards-conforming). C is a bit more lenient than C++ in this regard. – James McNellis May 15 '10 at 18:22
  • So what your saying is that those lines are illegal in newer versions of C++? – Leif Andersen May 15 '10 at 18:35
  • 4
    What it's saying is that those lines are illegal in C++ if the header include any standard header files, and that it will be illegal period in the next version of the C++ standard. – KTC May 15 '10 at 18:40
  • Ah, okay. Well the header file does #include , so perhaps I do need to find another way. – Leif Andersen May 15 '10 at 18:50
  • @Leif I think standard library refers to C++ library, rather than C. python.h is C only so you might be okay. alternatively, run header file through external preprocessor, for example m4 or Perl, this way C++ will never know – Anycorn May 15 '10 at 18:54
  • @KTC: Actually, the rules haven't changed in C++0x; I've fixed that answer to the other question so that it is correct. My apologies. @aaa: The C++ standard library includes the C standard library headers. – James McNellis May 15 '10 at 19:28
  • @James, okay, that makes more sense, I was wondering how many C classes would incorporate C++ libraries...but even though they are including standard libraries, it doesn't matter, just because the rules didn't change, yes? – Leif Andersen May 15 '10 at 19:33
  • 2
    No offense to @aaa, but @Leif: I strongly consider you don't do this answer. It's illegal in terms of the language, and completely unnecessary. Just change `class` to `class_` and be done with it. – GManNickG May 16 '10 at 05:21
  • @GMan no problem, I put Makefile/Perl rule in answer – Anycorn May 16 '10 at 18:26
  • If the header WAS made for C and not CPP, you also need to wrap it thus: extern "C" { #include "cheader.h" } – Chris Becke Jun 02 '10 at 09:13
8

If this is declaration only, then the variable names don't matter at all. You can completely remove them or change them how you please. This is because the declaration merely defines the name and type of the function, which is:

int BPY_class_validate(const char *, PyObject *, PyObject *,
                        BPY_class_attr_check*, PyObject **);

But if you want the names (to be a bit more descriptive), you can just throw an underscore at the end of what you have:

int BPY_class_validate(const char *class_type, PyObject *class_,
                        PyObject *base_class, BPY_class_attr_check* class_attrs, 
                        PyObject **py_class_attrs);

This won't break any other code.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
3

You can always use #ifdef __cplusplus to create a declaration specific for C++ in that header

Axarydax
  • 16,353
  • 21
  • 92
  • 151
3

You will need to modify the header to replace 'class' with something else in order to compile it as C++.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
1

As a practical matter, you're out of luck. "class" is a reserved word, you can't use it as a variable identifier.

I suppose you could do preprocessor tricks, like

#define class othername

But really that's silly, too, because it'll make your code confusing and prevent you from using real classes.

Just bite the bullet and rename the parameter 'theclass' or something.

Larry Gritz
  • 13,331
  • 5
  • 42
  • 42