__declspec是一个Microsoft Visual C++特定的编译器属性开关。括号中指
明的是哪一个属性生效。关于__declspec的其他属性可以百度“__declspec msdn”

查看微软的官方帮助。也可以参看博客中转载的文章。

言归正传。__declspec(selectany)在MSDN中的说明是这样的:

Tells the compiler that the declared global data item (variable or object) is a pick-any

COMDAT (a packaged function). At link time, if multiple a definitions of COMDAT are

seen, the linker picks one and discards the rest. Selectany can be used in initializing

global data defined by headers,when the same header appears in more than one

source file.

简单翻译一下:告诉编译器定义的全局数据项(变量或对象)这是一套能被任

意挑选的COMDAT(一套函数)。在链接时,如果多个COMDAT的定义被找到,

链接器将挑选一个并剔除其他的多余的。Selectany可以被用于当定义有初始化全局

变量数据的头文件被应用于多于一个的源文件时。

我这样的翻译还是挺虚的,直白了说:当在头文件定义全局变量,并且这个头

文件被include多次时可以用这个开关剔除由于多次include而产生的重定义。

看起来这个开关很有用,但这个开关我们用得并不多。很明显,根据msdn的解释,

对于定义常量这个开关是用不上的了,而全局变量一般来说定义在cpp中,那么这个

开关有什么用呢?

这正是这篇文章要讨论的主题。

(1)基于程序结构的整齐,统一将全局变量定义在一个全部cpp都引用的头文件,

这样也就避免了在每个cpp中用extren导入外部变量。当然,这随你的习惯了。

(2)模板的设计。类模板,函数模板,这些肯定不会只被一个cpp所使用,按照一般

的习惯都是写在头文件的。但是对于模板,其实现是在编译期完成的,那就要求必须

在编译的时候同时找到模板的定义和实现,也就是意味着不可能像以前的习惯一样,

将类的声明放在头文件,将实现放在cpp中。那么模板类的静态成员变量怎么办呢?

类的静态成员必须在类外部初始化,如果是全写在头文件,当头文件include多于一次

的时候就会出现类的静态变量重定义的问题,可以做一个简单的实验:

sy.h:

class A
{
public:static int u;
};
int A::u=1;

1.cpp:

#include"sy.h"int main()
{return 0;
}

2.cpp:

#include"sy.h"

就这样三个文件,在一个工程中,组建一下(编译没问题,问题出在链接的时

候),就会出现:

2.obj : error LNK2005: "public: static int A::u" (?u@A@@2HA) already defined in sy.obj
Debug/sy.exe : fatal error LNK1169: one or more multiply defined symbols found

这时候就只能使用__declspec(selectany)去解决了,将sy.h的第六行改为:

__declspec(selectany) int A::u=1;

即可解决问题。

下面来讨论一个问题,那么看下面的代码:

key.h:

const char *Function[28]=
{"menu","exit","rad","sin","cos","tan","sec","csc","cot","asin","acos","atan","acsc","asec","acot","sh","ch","th","ash","ach","ath","log","lg","ln","sum","mul","A","C"
};

这个头文件被include了多次。我的原意的是希望建立一个字符串的数

组常量,上面说了定义常量并不需要用这个开关,但为什么还是会出

现重定义的问题呢?而且确实能用__declspec(selectany)去解决。

实际上这个可以不用__declspec(selectany)去解决,写成这样即可:

const char* const Function[28]=
{"menu","exit","rad","sin","cos","tan","sec","csc","cot","asin","acos","atan","acsc","asec","acot","sh","ch","th","ash","ach","ath","log","lg","ln","sum","mul","A","C"
};

如果在看了我的原意之后并没有发现一开始给的代码有什么问题,请想

一下用__declspec(selectany)去解决虽然没有问题,但符合我的原意吗?

这样Function的内容到底是变量还是常量?

__declspec(selectany)的作用相关推荐

  1. 从static变量导出问题解析 __declspec(dllexport) 和 __declspec(dllimport)的作用

    这段时间要把tinyxml从静态库弄成动态库,要用到__declspec(dllexport)和__declspec(dllimport)来导出dll和lib文件.终于弄明白了export和impor ...

  2. __declspec(dllexport)的作用

    加了之后发现,用ollydbg导入dll,可以自动判断某个函数是导出函数 转载于:https://www.cnblogs.com/Dream-Chaser/p/4906537.html

  3. c++ 中__declspec 的用法

    语法说明: __declspec ( extended-decl-modifier-seq ) 扩展修饰符: 1:align(#)     用__declspec(align(#))精确控制用户自定数 ...

  4. __declspec关键字详细用法

    __declspec关键字详细用法 2009-01-21 16:23 __declspec用于指定所给定类型的实例的与Microsoft相关的存储方式.其它的有关存储方式的修饰符如static与ext ...

  5. __declspec

    __declspec __cdecl和__stdcall都是函数调用规范(还有一个__fastcall),规定了参数出入栈的顺序和方法, 如果只用VC编程的话可以不用关心,但是要在C++和Pascal ...

  6. 【转】__declspec用法详解

    __declspec用法详解 __declspec用于指定所给定类型的实例的与Microsoft相关的存储方式.其它的有关存储方式的修饰符如static与extern等是C和 C++语言的ANSI规范 ...

  7. extern C __declspec(dllexport) __declspec(dllimport) 和 def

    前面的extern "C"  __declspec(dllexport)  __declspec(dllimport)都是用于函数或者变量,甚至类的声明的(可以把extern &q ...

  8. __declspec(dllimport)

    我相信写WIN32程序的人,做过DLL,都会很清楚__declspec(dllexport)的作用,它就是为了省掉在DEF文件中手工定义导出哪些函数的一个方法.当然,如果你的DLL里全是C++的类的话 ...

  9. 【转】extern “C“和__declspec(dllexport)以及__declspec(dllimport) 和def的简单解析

    转自:https://blog.csdn.net/xupan_jsj/article/details/9028759 前面的extern "C"  __declspec(dllex ...

最新文章

  1. 大话日志分析与管理,答题赠书活动
  2. [转载]判断IE浏览器-世界上最短的代码
  3. android 点击字体,图片背景效果一起变换Demo
  4. jquery清空div内容_jQuery常用功能
  5. qlikview连接mysql_QlikView通过ODBC连接IBMDB2
  6. fusioncharts同一页面显示2个仪表盘,且以java字符串作为xml数据
  7. android之seekbar
  8. 《Python Cookbook 3rd》笔记(3.2):执行精确的浮点数运算
  9. 华为徐直军:今年超3亿设备搭载鸿蒙系统
  10. pyqt 取鼠标处文字_顶级玩家首选 赛睿QcK Edge鼠标垫体验评测
  11. D-Link service.cgi远程命令执行漏洞复现
  12. python librosa将哼唱旋律转换为音符
  13. word流程图怎么使箭头对齐_怎样在word中绘制流程图方框间距相同,排列整齐,箭头笔直...
  14. 科学计算机的英文怎么拼读,科学的英语读音,科学的英文怎么读谐音。
  15. 关于UEFI启动+GPT分区 的一些经验
  16. Android App Bundle 和Unity AAB BundleTools
  17. 动作捕捉(Motion Capture)文件BVH的解读笔记
  18. [跑步] 7种方法增强耐力
  19. LeetCode - 644 子数组最大平均数 II
  20. 安卓开发视频处理框架!2021年这些高频面试知识点最后再发一次,全网疯传

热门文章

  1. 常用的函数式接口_Predicate接口_默认方法ornegate
  2. 什么是saashrm
  3. ES6新特性之函数优化-箭头函数
  4. 常见软件架构方式的区别
  5. 电脑装服务器系统好处,服务器选用Linux系统的几个好处
  6. php显示评委打分情况代码,评委打分表自动汇总计算得分
  7. Nginx教程-http_core_module变量
  8. python之路day9_亮仔的Python之路Day9——Python知识体系重组
  9. STM32CubeMX系列教程 5.0版本环境开发——1.工程搭建
  10. 助力产教融合,阿里云教育一体机发布