相关疑难解决方法(0)

没有"静态"或"外部"的"内联"在C99中是否有用?

当我尝试构建此代码时

inline void f() {}

int main()
{
    f();
}
Run Code Online (Sandbox Code Playgroud)

使用命令行

gcc -std=c99 -o a a.c
Run Code Online (Sandbox Code Playgroud)

我收到链接器错误(未定义引用f).如果我使用static inlineextern inline代替just inline,或者如果我使用-O(因此函数实际内联),则错误消失.

这种行为似乎在C99标准第6.7.4(6)段中定义:

如果转换单元中函数的所有文件范围声明都包含inline函数说明符extern,则该转换单元中的定义是内联定义.内联定义不提供函数的外部定义,也不禁止另一个转换单元中的外部定义.内联定义提供了外部定义的替代,翻译器可以使用该定义在同一翻译单元中实现对该功能的任何调用.未指定对函数的调用是使用内联定义还是使用外部定义.

如果我理解了这一切,inline那么如果还有一个具有相同名称的外部函数,那么具有上例中定义的函数的编译单元只会一致地编译,而且我永远不知道我自己的函数或外部函数是否被调用.

这种行为不是完全愚蠢吗?在inline没有staticextern在C99中定义函数是否有用?我错过了什么吗?

答案摘要

当然我错过了什么,行为并不愚蠢.:)

正如Nemo所解释的那样,我们的想法是定义函数

inline void f() {}
Run Code Online (Sandbox Code Playgroud)

在头文件中只有一个声明

extern inline void f();
Run Code Online (Sandbox Code Playgroud)

在相应的.c文件中.只有extern声明才会触发生成外部可见的二进制代码.确实没有inline在.c文件中使用 - 它只在标题中有用.

正如Jonathan的回答中引用的C99委员会基本原理所阐述的那样,inline所有关于编译器优化都需要在调用的站点上看到函数的定义.这只能通过将标题放在标题中来实现,当然,标题中的定义在编译器每次看到它时都不能发出代码.但由于编译器不是强制实际内联函数,因此必须在某处存在外部定义.

c inline c99

91
推荐指数
2
解决办法
3万
查看次数

警告:忽略使用属性warn_unused_result声明的'scanf'的返回值

#include <stdio.h>

int main() {
    int t;
    scanf("%d", &t);
    printf("%d", t);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用ideone.com编译了上面的C代码,并弹出以下警告:

prog.c:在函数'main'中:
prog.c:5:警告:忽略'scanf'的返回值,使用属性warn_unused_result声明

有人能帮我理解这个警告吗?

c

49
推荐指数
4
解决办法
7万
查看次数

调用内联函数时未定义的引用

我从GCC 4.8.1得到一个非常奇怪的错误,内联函数.

我在头文件(debug.herror.h)中定义了两个几乎相同的内联函数src/include/,唯一的区别是它们打印的内容 - DEBUG:消息的一个前缀,另一个%s: error: %s(程序名,错误消息).在定义内联函数和编译调试版本时(因此它设置宏DEBUG=1),我得到了许多未定义的引用错误:

src/main_debug.o
  gcc -osrc/main_debug.o src/main.c -c -Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g -DCC="\"gcc\"" -DCFLAGS="\"-Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g\"" -DDEBUG=1 -DBTCWATCH_VERSION="\"0.0.1\""

src/lib/btcapi_debug.o
  gcc -osrc/lib/btcapi_debug.o src/lib/btcapi.c -c -Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g -DCC="\"gcc\"" -DCFLAGS="\"-Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og -g\"" -DDEBUG=1

src/lib/libbtcapi_debug.a
  ar rc src/lib/libbtcapi_debug.a src/lib/btcapi_debug.o
  ranlib src/lib/libbtcapi_debug.a

src/lib/cmdlineutils_debug.o
  gcc -o src/lib/cmdlineutils_debug.o src/lib/cmdlineutils.c -c -Wall -Wextra -Wpedantic -std=gnu11 -march=native -Og …
Run Code Online (Sandbox Code Playgroud)

c inline function undefined header-files

46
推荐指数
2
解决办法
3万
查看次数

内联定义导致程序中未解析的符号

所以我有以下代码:

#include <stdio.h>

#define MAX(a,b) (a) > (b) ? a : b

int abs(int a)
{
    if (a > 0)
        return a;
    else
        return a*-1;
}

inline int avg(int a, int b)
{
    return (a+b)/2;
}

int math_max(int a, int b)
{
    return (avg(a,b)+abs(avg(a,b)-b));
}

int main(int argc, char** argv)
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我编译它时:gcc -g test.c -o test我得到:

/tmp/ccZbHEju.o: In function `math_max':
test.c:(.text+0x33): undefined reference to `avg'
test.c:(.text+0x44): undefined reference to `avg'
collect2: error: ld returned 1 …
Run Code Online (Sandbox Code Playgroud)

c

9
推荐指数
0
解决办法
144
查看次数

C中头文件中的内联函数

我试图在线搜索一个好的答案,但没有得到一个我完全可以理解的答案.假设我有一个标题"add.h":

inline int add(int a, int b){ return a+b; }
Run Code Online (Sandbox Code Playgroud)

一个名为"adddouble.c"的文件:

#include "add.h"

int adddouble(int a, int b){ return 2*add(a,b); }
Run Code Online (Sandbox Code Playgroud)

一个名为"addsquare.c"的文件:

#include "add.h"

int addsquare(int a, int b){ return add(a,b)*add(a,b); }
Run Code Online (Sandbox Code Playgroud)

主文件"main.c":

#include<stdio.h>

int adddouble(int, int);
int addsquare(int, int);
int main(){
printf("add double = %d\n", adddouble(10,20));
printf("add square = %d\n", addsquare(10,20));
return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用gcc5.2.0来编译这些文件,但得到了:"架构x86_64的未定义符号:".如果我在add.h中添加静态到内联函数或添加声明"extern int add(int,int);" 到"adddouble.c",它成功编译没有错误.我是新的内联函数,我不知道如何解释和理解这种行为.谢谢

c inline

6
推荐指数
1
解决办法
1万
查看次数

gcc 无法在没有 -O2 的情况下内联函数

我最近遇到了在升级 debian 测试后编译一段代码的问题,得到了 gcc 6.2.1 编译器。我把它归结为这个简单的例子:

inline int func(void) {
    return 0;
}

int main (int argc, char **argv) {
    func();
}
Run Code Online (Sandbox Code Playgroud)

该代码不会与下面的编译:

gcc -o exec code.c # gcc 6.2.1

它失败了:

undefined reference to 'func'

我也在同一台主机上尝试过 gcc 4.8、4.9 和 5,但都失败了。如果我添加,它会编译:

gcc -o exec code.c -O2 # gcc 6.2.1

我真的很好奇为什么它与 -O2 标志一起工作,但不是没有,我希望这能工作?

c optimization gcc inline gcc6

3
推荐指数
1
解决办法
3360
查看次数

标签 统计

c ×6

inline ×4

c99 ×1

function ×1

gcc ×1

gcc6 ×1

header-files ×1

optimization ×1

undefined ×1