共享对象中代码重复问题:头文件语句多次执行的解决方法
解决头文件全局变量初始化重复执行的问题
问题根源
头文件里的const int x = funcC();是变量定义而非声明。虽然头文件加了#ifndef保护,但它只能防止单个编译单元(比如单个.cpp文件)重复包含头文件,没办法阻止多个编译单元(比如你的common.c和main1.c)各自包含头文件时,都会生成x的独立副本。每个编译单元在初始化全局变量x时,都会调用一次funcC(),所以就出现了多次打印的情况。
解决方案
方案1:把变量定义移到源文件,头文件只留声明
这是最传统也最兼容的做法:
- 修改
common.h,仅声明x:
// common.h #ifndef _COMMON_H #define _COMMON_H #include<iostream> int funcC(); extern const int x; // 仅做声明,不分配内存 #endif // _COMMON_H
- 在
common.c里定义并初始化x:
// common.c #include "common.h" #include <iostream> int funcC() { std::cout<<"HI HI HI"<<std::endl; return 2; } const int x = funcC(); // 全局唯一的定义,仅初始化一次
这样整个程序里只有一个x的实例,funcC()只会被调用一次。
方案2:用C++17的inline变量(推荐现代编译器)
如果你的编译器支持C++17及以上标准,可以直接给头文件里的变量加inline关键字,确保全局只有一个实例:
// common.h #ifndef _COMMON_H #define _COMMON_H #include<iostream> int funcC(); inline const int x = funcC(); // inline保证全局唯一定义,自动合并多编译单元的实例 #endif // _COMMON_H
这种方式不需要修改源文件,编译时编译器会自动处理重复定义问题,初始化只会执行一次。
方案3:用静态局部变量封装(避免全局变量)
如果不是必须用全局变量x,可以把它封装在函数里,用静态局部变量确保只初始化一次:
- 修改
common.h:
// common.h #ifndef _COMMON_H #define _COMMON_H #include<iostream> int getX(); // 提供获取x值的接口 #endif // _COMMON_H
- 在
common.c里实现:
// common.c #include "common.h" #include <iostream> static int funcC() { // 设为静态,仅在本文件可见 std::cout<<"HI HI HI"<<std::endl; return 2; } int getX() { static const int x = funcC(); // 静态局部变量,第一次调用时才初始化 return x; }
之后需要用x的地方调用getX()即可,funcC()只会在第一次调用getX()时执行一次。
内容的提问来源于stack exchange,提问作者sushant sharma
相关产品推荐
相关产品推荐

