假设我有以下情况
/* module a.c */
Data secret; /* data to remain hidden */
inline int veryShortProcedure( int d ) { /* using secret */ }
/* a.h */
int veryShortProcedure( int );
/* module b.c */
#include "a.h"
int procedure( int d ) {
/* something */
veryShortProcedure( d );
}
从任何 C 标准的角度来看,该代码都是不正确的,因为每当过程是内联的时,我都无法将其拆分为原型(prototype)和声明,因此我应该在 a.h 中定义它。
尽管如此,代码还是在 gcc 中使用 -std=gnu90 选项进行编译。我的问题是,它会做什么? gcc 会忽略我的内联声明吗?在我看来,以这种方式放置代码就像想要在链接器级别内联函数一样,这是荒谬的。
这种情况下的常见做法是什么?我应该牺牲安全性还是效率(跳到短程序效率有点低)?
最佳答案
您的代码是正确的 C99(和 C11),但它所做的事情可能与您想象的不同。
看到内联
声明和非内联
的编译单元必须发出以下符号:产生的对象。正常用法是
-
header 中的
inline
定义(也用作声明) 文件。因此,该定义在每个编译单元中都是可见的,并且编译器可能会在他认为合适的任何时候使用(或不使用)。- 一个编译单元中的非
内联
声明,用于在该编译单元中发出一次符号
一旦您使用多个编译单元中的 .h
,您的代码可能会大吃一惊。链接时会出现重复的符号。
此外,您的 secret 声明
也不是应有的样子。您选择的形式是一个暂定定义,可能存在相同的问题,即导致多重定义的符号。
将非inline
声明放入.c文件中,在secret
声明前加上extern
,一切都会如其所愿是。
关于c - 纯c中的内联函数和数据隐藏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20314795/