Changing the structure to a class (and other type changes) and creating an ABI / code

This is a well-established and canonical reference question that in C ++, structures and classes are largely interchangeable when writing code manually.

However, if I want to link existing code, can I expect it to have any meaning (i.e. break, nose daemons, etc.) if I re-create the structure as a class or vice versa in the header after Was the original code created?

So, the situation is that the type was compiled as a structure (or class), and I then change the header file to another declaration before including it in my project.

The real use case is that I automatically generate code using SWIG, which generates different output depending on whether they are given by structures or classes; I need to change one to the other in order to get it for the correct interface.

An example here (Irrlicht, SVertexManipulator.h) is this:

struct IVertexManipulator { }; 

I update it mechanically as:

 /*struct*/class IVertexManipulator {public: }; 

The source library compiles with the original headers intact. The wrapper code is created using modified forms and compiled using them. Then they are combined into the same program for collaboration. Suppose I use the same compiler for both libraries.

Is it something like undefined? "Undefined" but expected to work with real-world compilers? Absolutely permissible?

Other similar changes that I make include removing some default values ​​from the parameters (to prevent ambiguity) and removing declarations from several classes where the type does not appear in SWIG (which changes the structure of the class, but my reasoning is that the generated code should need this information, only for reference to member functions). Again, how much harm could this have caused?

eg. IGPUProgrammingServices.h :

 s32 addHighLevelShaderMaterial( const c8* vertexShaderProgram, const c8* vertexShaderEntryPointName/*="main"*/, E_VERTEX_SHADER_TYPE vsCompileTarget/*=EVST_VS_1_1*/, const c8* pixelShaderProgram=0, ... 

CIndexBuffer.h :

 public: //IIndexList *Indices; 

... and so on. Other changes include replacing some types of template parameters with their typedefs and removing the packed attribute from some structures. Again, it seems like there should be no problem if the modified structure declarations are never used in machine codes (just to generate names to refer to access functions in the main library), but how reliable is this? Ever been up?

+6
source share
1 answer

This is technically undefined behavior.

3.2 / 5:

A program can have several class type definitions, [... or other things that must be defined in the header files ...], provided that each definition is displayed in a different translation unit and provides definitions that satisfy the following requirements. Given such an object named D , defined in several translation units, then

  • each definition of D must consist of the same sequence of tokens; and

  • ...

... If the definitions of D satisfy all these requirements, the program should behave as if there were one definition of D If the definitions of D do not satisfy these requirements, then the behavior is undefined.

Essentially, you change the first token from struct to class and insert the public and : tokens into it. The standard does not allow this.

But in all compilers that I'm familiar with, this will be good in practice.


Other similar changes I make include removing some default values ​​from the parameters (to prevent ambiguity)

This is actually formally permitted if the declaration is not included in the class definition. Different translation units and even different areas in TU can define different arguments to the function by default. So you are probably well there too.

Other changes include replacing some types of template parameters with their typedefs

Also formally permitted outside the class definition: two function declarations that use different naming methods of the same type refer to the same function.

... removing field declarations ... and removing a packed attribute from multiple structures

You are now in a serious danger zone. I am not familiar with SWIG, but if you do this, you better be sure that code using these "incorrect" definitions will never be:

  • create or destroy an object of type class

  • define a type that inherits or contains a class type member

  • use a non-static class data item

  • call an inline or template function that uses a non-static class data element

  • call a member function of a virtual type of a class or derived type

  • try to find sizeof or alignof class type

+2
source

Source: https://habr.com/ru/post/970048/


All Articles