C++ 2个结构体重名,g++有办法发现吗?

我有2个cpp文件,2个里面各自有一个结构体,成员不一样,但是名字恰好一样。
我使用的时候,就会出问题,2个结构体混淆了,可能会导致程序崩溃。
用g++编译的时候,g++并没有报错。
有没有方法,能主动发现类似的错误?

下面的源码,运行时会直接崩溃。
而且,看打印,test_fun.cpp里面的变量,析构时,会调用main.cpp里面的析构函数。

#include <stdio.h>
#include <string>
#include <vector>
#include <unistd.h>

#define    ht_log_info(xx,args...)    fprintf(stderr, xx"\n", ##args)


int test_key_fun1();
int test_key_fun2();
int test_key_fun3();

int a;
typedef struct key_info_s{
    std::string key;
    std::string value;
    ~key_info_s(){
           ht_log_info("main::key_info_s: delete ,size=%d", sizeof( struct key_info_s));
       }
}KEY_INFO_T;

class KEY_ITEM_T{
    std::string key;
    std::string value;
    int a;
    int b;
    int c;
};


int main()
{


   // test_key_fun2();
    test_key_fun3();
    test_key_fun1();
     KEY_INFO_T aaaa;
    while(1)
    {
        usleep(1e6);

        int a = 34;
        int b= 34;
        int c = a + b;
        ht_log_info("c=%d", c);
    }

    return 0;
}



static int m_test_key1=13;
#include <stdio.h>
#include <string>
#include <vector>

#define    ht_log_info(xx,args...)    fprintf(stderr, xx"\n", ##args)


typedef struct key_info_s{
    int x;
    int y;
    std::string key;
    std::string value;
    int a;
    int b;
    int c;

    ~key_info_s(){
           ht_log_info("test_fun.cpp::key_info_s: delete ,size=%d", sizeof( struct key_info_s));
       }
}KEY_INFO_T;

class KEY_ITEM_T{
    public:
    int x;
    int y;
    std::string key;
    std::string value;
    int a;
    int b;
    int c;
};

static std::vector<KEY_INFO_T>   m_key_info_list;
extern int a;
int test_key_fun1()
{
    KEY_INFO_T key_info;
    key_info.x = 11;
    key_info.y = 12;
    key_info.key = "abcd";
    key_info.value = "123";
    key_info.a = 21;
    key_info.b = 22;
    key_info.c = 23;

    m_key_info_list.push_back(key_info);

    KEY_INFO_T &key_info2 = m_key_info_list[0];
    ht_log_info("size=%d, [%d][%d][%s][%s]", sizeof(KEY_INFO_T), key_info2.x, key_info2.y, key_info2.key.data(), key_info2.value.data());
    ht_log_info("size=%d, [%d][%d][%d]", sizeof(KEY_INFO_T), key_info2.a, key_info2.b, key_info2.c);

    return 0;
}


int test_key_fun2()
{
    ht_log_info("test_key_fun2:m_test_key1=%d", m_test_key1);
    ht_log_info("a=%d", a);
    ht_log_info("a=%lf", a);
    return 1;
}

static std::vector<KEY_ITEM_T>   m_key_item_list;
int test_key_fun3()
{
    KEY_ITEM_T key_info;
    key_info.x = 11;
    key_info.y = 12;
    key_info.key = "abcd";
    key_info.value = "123";

    m_key_item_list.push_back(key_info);

    KEY_ITEM_T &key_info2 = m_key_item_list[0];
    ht_log_info("size=%d, [%d][%d][%s][%s]",sizeof(KEY_ITEM_T),  key_info2.x, key_info2.y, key_info2.key.data(), key_info2.value.data());

    return 0;
}



你把结构体 都定义到 头文件里 包含进来 就会报错了

建议使用命名空间

  • 这篇博客: c++工程中调用c文件或c库的方法中的 1.在编译时对.c和.cpp文件都使用g++编译 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  •   要是想要使用g++直接编译c文件,那么一种就是直接把.c文件当成c++文件编译。这样可能会造成.c文件于.cpp文件的冲突,不使用。使用的还是将.c文件按照编译c文件的方式编译(也就是按照gcc方式编译),那么就需要使用到extern “C”{ }编译声明了。这个声明的就表示在{}内部的代码完全按照c程序的方式去编译和链接(即使使用的时g++编译器)。需要在.c和.h文件中都使用 extern “C”{ }的方式包含.c代码段。代码实现如下:

    /************************test1.c***************************/
    #ifdef __cplusplus
    extern "C"{
    #endif
    	//add函数定义
    	int add(int a,int b)
    	{
    		return a+b;
    	}
    	//sub函数定义
    	int sub(int a,int b)
    	{
    		return a-b;
    	}
    #ifdef __cplusplus
    }
    #endif
    
    /************************test1.h***************************/
    #ifndef __TEST1
    #define __TEST1
    
    #ifdef __cplusplus
    extern "C"{
    #endif
    	
    int add(int a,int b);		//	add函数声明
    int sub(int a,int b);		//	sub函数声明
    	
    #ifdef __cplusplus
    }
    #endif
    	
    #endif
    
    /************************test2.cpp***************************/
    #include <iostream>
    #include "test1.h"
    using namespace std;
    int main(void)
    {
    	int a = 10;
    	int b = 11;
    	int c = add(a,b);
    	cout<<"a+b="<<c<<endl;
    }
    

    编译:g++ test1.c test2.cpp 生成a.out可执行文件。
    执行./a.out输出:a+b=21
    编译和指向完全正确。
    但是这种方式不常用,因为正常我们调用的都是别人使用gcc编译好的.o文件库,不会让我们自己编译源文件,因此引出第二种常用的方法。