Undef a typedef in C++?

时光毁灭记忆、已成空白 提交于 2019-12-18 13:01:24

问题


I am working on a huge project which has one file A.h whose code has a line

typedef unsigned __int16   Elf64_Half;

Also since I am building on Linux and using dlinfo function, I have to include link.h file in my project. And this is where it creates a conflict because I have two typedefs having the same name Elf64_Half. (Linux link.h includes elftypes.h and it too has: typedef unsigned short Elf64_Half;).

What do I do in such a case? Is the only option I have, to change my typedef in a.h? Remember it is not too easy because the project is huge and I will have to make a change in several places.

Is there a way to undef a typedef or something?


回答1:


For clarification, Rahul Manne gave an easy solution. Do

#define Elf64_Half The_Elf64_Half_I_dont_care
#include<link.h>
#undef Elf64_Half
#include<A.h>

/*
 * Code here and use Elf64_Half from A.h as you like.
 * However, you can't use Elf64_Half from link.h here
 * or you have to call it The_Elf64_Half_I_dont_care.
 *
 */

This will substitute each Elf64_Half in link.h with The_Elf64_Half_I_dont_care and thus you get no conflicts with A.h. As long as you don't want to use Elf64_Half of link.h explicitly that will work with no problems. You just have to remember that Elf64_Half from link.h is now called The_Elf64_Half_I_dont_care in case you ever have to use it explicitly in this file.




回答2:


What do I do in such a case?

A common remedy is to put the one which needs the least visibility behind a "compilation firewall". That is, to create your own abstraction/interface which provides the functionality you need, and then to limit the visibility of the included file to the *.cpp by including it in that *.cpp only. Of course, that *.cpp file would also not be permitted to include the header which has the other definition of the typedef.

Then the declarations won't cause conflict because they will never be visible to the same translation unit.

In your example, you'd likely create a wrapper over the dlinfo() functionalities you need. To illustrate:

DLInfo.hpp

namespace MON {
class DLInfo {
 public:
 /* ...declare the necessary public/client functionality here... */
 int foo();
 ...
};
}

DLInfo.cpp

#include "DLInfo.hpp"

// include the headers for dlinfo() here.
// these includes should not be in your project's headers
#include <link.h>
#include <dlfcn.h>

// and define your MON::DLInfo implementation here, with full
// ability to use dlinfo():

int MON::DLInfo::foo() {
 ...
}

...



回答3:


Here's a little work around I figured out: If you define it as something else first, then you can typedef it later. See here in the example (I'm on OS X using g++):

#import <iostream>
using namespace std;

typedef unsigned int uint32;

int main() {
  cout << sizeof(uint32) << endl;
}

The output of this program is

4

Now consider this modified program:

#import <iostream>
using namespace std;

typedef unsigned int uint32;
#define uint32 blah
typedef unsigned long uint32;

int main() {
  cout << sizeof(uint32) << endl;
}

The output of this program is

8

So to answer your question, you would add a line to your code:

#define Elf64_Half Elf64_Half_custom

For clarity, this works because you are basically renaming them all, but doing so with a single command instead of having to change all of your own names.



来源:https://stackoverflow.com/questions/27435565/undef-a-typedef-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!