Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undef a typedef in C++?

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?

like image 293
voidMainReturn Avatar asked Dec 12 '14 01:12

voidMainReturn


2 Answers

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.

like image 77
imix Avatar answered Sep 29 '22 08:09

imix


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() {
 ...
}

...
like image 38
justin Avatar answered Sep 29 '22 09:09

justin