Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory-layout compatibility between C and C++

Tags:

c++

c

I'm building a C++ library which uses many functions and struct's defined in a C library. To avoid porting any code to C++, I add the typical conditional preprocessing to the C header files. For example,

//my_struct.h of the C library
#include <complex.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
  double d1,d2,d3;
#ifdef __cplusplus
  std::complex<double> z1,z2,z3;
  std::complex<double> *pz;
#else
  double complex z1,z2,z3;
  double complex *pz;
#endif
  int i,j,k;
} my_struct;

//Memory allocating + initialization function
my_struct *
alloc_my_struct(double);

#ifdef __cplusplus
}
#endif

The implementation of alloc_my_struct() is compiled in C. It simply allocates memory via malloc() and initializes members of my_struct.

Now when I do the following in my C++ code,

#include "my_struct.h"
...
  my_struct *const ms = alloc_my_struct(2.);

I notice that *ms always have the expected memory layout, i.e., any access such as ms->z1 evaluates to the expected value. I find this really cool considering that (correct me if I'm wrong) the memory layout of my_struct during allocation is decided by the C compiler (in my case gcc -std=c11), while during access by the C++ compiler (in my case g++ -std=c++11).

My question is : Is this compatibility standardized? If not, is there any way around it?

NOTE : I don't have enough knowledge to argue against alignment, padding, and other implementation-defined specifics. But it is noteworthy that the GNU scientific library, which is C-compiled, is implementing the same approach (although their structs do not involve C99 complex numbers) for use in C++. On the other hand, I've done sufficient research to conclude that C++11 guarantees layout compatibility between C99 double complex and std::complex<double>.

like image 840
downhillFromHere Avatar asked Aug 24 '15 18:08

downhillFromHere


People also ask

What is memory layout in C?

A C program memory layout in C mainly comprises six components these are heap, stack, code segment, command-line arguments, uninitialized and initialized data segments. Each of these segments has its own read, write permissions.

How is structure stored in memory in C?

Struct members are stored in the order they are declared. (This is required by the C99 standard, as mentioned here earlier.) If necessary, padding is added between struct members, to ensure that the latter one uses the correct alignment. Each primitive type T requires an alignment of sizeof(T) bytes.

What is heap segment in C?

Heap is the segment where dynamic memory allocation usually takes place. When some more memory need to be allocated using malloc and calloc function, heap grows upward. The Heap area is shared by all shared libraries and dynamically loaded modules in a process.

How does the stack work in C?

A stack is a linear data structure, collection of items of the same type. Stack follows the Last In First Out (LIFO) fashion wherein the last element entered is the first one to be popped out. In stacks, the insertion and deletion of elements happen only at one endpoint of it.


1 Answers

C and C++ do share memory layout rules. In both languages structs are placed in memory in the same way. And even if C++ did want to do things a little differently, placing the struct inside extern "C" {} guarantees C layout.

But what your code is doing relies on C++ std::complex and C99 complex to be the same.

So see:

  • https://gcc.gnu.org/ml/libstdc++/2007-02/msg00161.html
  • C Complex Numbers in C++?
like image 141
Zan Lynx Avatar answered Sep 21 '22 14:09

Zan Lynx