相关疑难解决方法(0)

C宏可以包含临时变量吗?

我有一个我需要宏功能的功能.该函数包含临时变量,我不记得是否有关于在宏替换中使用临时变量的规则.

long fooAlloc(struct foo *f, long size)
{
   long      i1, i2;
   double   *data[7];

   /* do something */
   return 42;
}
Run Code Online (Sandbox Code Playgroud)

MACRO表格:

#define ALLOC_FOO(f, size) \
{\
   long      i1, i2;\
   double   *data[7];\
\
   /* do something */ \
}
Run Code Online (Sandbox Code Playgroud)

这个可以吗?(即没有令人讨厌的副作用 - 除了通常的那些:不是"类型安全"等).顺便说一句,我知道"宏是邪恶的" - 在这种情况下我只需要使用它 - 没有多少选择.

c c-preprocessor

11
推荐指数
4
解决办法
2万
查看次数

C99内联的理念是什么?

inline在C99 感到困惑.

这就是我想要的:

  1. 我希望我的函数在任何地方都被内联,而不仅仅局限于一个翻译单元(或一个编译单元,一个.c文件).
  2. 我希望函数的地址一致.如果我在函数指针中保存函数的地址,我希望函数可以从指针调用,我不希望在不同的翻译单元中重复相同的函数(基本上,我的意思是没有static inline).

C++就是inline这样做的.

但是(如果我错了请纠正我)在C99中没有办法得到这种行为.

我可以使用static inline,但它会导致重复(不同翻译单元中相同功能的地址不一样).我不希望这种重复.

所以,这是我的问题:

  1. inlineC99的理念是什么?
  2. 这个设计对C++的方法有什么好处?

参考文献:

  1. 这是一个高度评价C99的链接inline,但我不明白为什么.这只"仅在一个编译单元中"限制真的那么好吗?
    http://gustedt.wordpress.com/2010/11/29/myth-and-reality-about-inline-in-c99/
  2. 这是C99的基本原理inline.我读过它,但我不明白.
    没有"静态"或"外部"的"内联"在C99中是否有用?
  3. 一篇不错的文章,提供了使用inline函数的策略.
    http://www.greenend.org.uk/rjk/tech/inline.html

答案摘要

如何inline在C99中获得C++ 行为(是的,我们可以)

head.h

#ifndef __HEAD_H__
#define __HEAD_H__

inline int my_max(int x, int y) {
    return (x>y) ? (x) : (y);
}

void call_and_print_addr();

#endif
Run Code Online (Sandbox Code Playgroud)

src.c

#include "head.h"
#include <stdio.h>

// This is necessary! And it should occurs and only occurs …
Run Code Online (Sandbox Code Playgroud)

c c99 extern inline-functions

9
推荐指数
1
解决办法
511
查看次数

如果内联函数使用fprintf,为什么需要声明为static?

我正在重构一些C代码并对因子部分进行单元测试(使用Google Test).在循环中多次使用了一个片段,因此为了将其暴露给测试,我将其作为inline头文件中的函数进行了考虑,该头文件demo.h还包括一些其他非inline函数的声明.简化版如下:

#ifndef DEMO_H_
#define DEMO_H_
#ifdef __cplusplus
extern "C" {
#endif
inline void print_line(FILE* dest, const double * data, int length) {
    for (int s = 0; s < length; s++)
        fprintf(dest, "%lf ", data[s]);
    fprintf(dest, "\n");
}
#ifdef __cplusplus
}
#endif
#endif /* MK_H_ */
Run Code Online (Sandbox Code Playgroud)

我的测试代码

#include "gtest/gtest.h"
#include "demo.h"
#include <memory>
#include <array>
#include <fstream>

TEST (demo, print_line) {
    std::array<double,4> test_data = {0.1, 1.4, -0.05, 3.612};

    const char* testfile = "print_line_test.txt"; …
Run Code Online (Sandbox Code Playgroud)

c c++ static inline

9
推荐指数
1
解决办法
3309
查看次数

C,内联函数和GCC

如果我有:

inline int foo(void)
{
   return  10 + 3;
}

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

使用GCC,文件编译得很好,但链接器返回 undefined reference to foo

相反,如果我删除inline链接器很高兴!

看起来链接器可以看到外部定义的标识符,但内联定义的标识符不是.

此外,如果我使用-O3标志编译,链接器将看到内联定义的标识符.

有什么问题?

c

8
推荐指数
1
解决办法
1699
查看次数

什么时候"内联"关键字在C中有效?

那么,标准无法保证inline函数实际内联; 必须使用宏才能获得100%的保证.无论inline关键字如何,编译器总是根据自己的规则决定哪个函数内联或不内联.

那么,inline当使用现代编译器(如最新版本的GCC)时,关键字何时会对编译器的作用产生什么影响?

c inline-functions

8
推荐指数
1
解决办法
267
查看次数

__attribute __((弱))和静态库

我想在代码中引入一个弱符号,但是,当使用* .a文件时,我无法理解它的行为。

这是我的最小示例:

文件啊:

void foo() __attribute__((weak));
Run Code Online (Sandbox Code Playgroud)

文件ac:

#include "a.h"
#include <stdio.h>

void foo() { printf("%s\n", __FILE__); }
Run Code Online (Sandbox Code Playgroud)

文件BC:

#include <stdio.h>

void foo() { printf("%s\n", __FILE__); }
Run Code Online (Sandbox Code Playgroud)

文件main.cpp:

#include "a.h"
#include <stdio.h>

int main() { if (foo) foo(); else printf("no foo\n"); }
Run Code Online (Sandbox Code Playgroud)

现在,根据我使用* .o文件(make -c a.cmake -c b.c)还是* .a文件(ar cr a.oar cr b.o),输出是不同的:

1)g++ main.cpp a.o b.o打印bc
2)g++ main.cpp b.o a.o打印bc
3)不g++ main.cpp a.a b.a …

c++ g++

8
推荐指数
1
解决办法
4539
查看次数

如何在C99中正确内联和使用内联函数?(构建失败)

执行cc -std=c99 example.c以下简化example.c文件:

inline void a()
{
}

int main()
{
   a();

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

得到我:

在函数`main'中:
example.c :(.text + 0x7):未定义引用'
a'collect2:ld返回1退出状态

据我所知,这与C99标准的要求有关,要求在无法内联的情况下使用的每个内联非静态函数的另一个定义?如果是这样的话,我猜我可以这样做static inline,但我不想让它在以后咬我,那么这里最好的做法是什么呢?显然,我想坚持C99,我想内联一些功能.(是的,我知道编译器通常知道什么内联而不被告知,但我有我的理由)

c inline c99

7
推荐指数
2
解决办法
1141
查看次数

C内联函数和"未定义外部"错误

我正在尝试用内联函数替换一些宏子程序,因此编译器可以优化它们,因此调试器可以进入它们,等等.如果我将它们定义为普通函数,它可以工作:

void do_something(void)
{
  blah;
}

void main(void)
{
  do_something();
}
Run Code Online (Sandbox Code Playgroud)

但如果我将它们定义为内联:

inline void do_something(void)
{
  blah;
}

void main(void)
{
  do_something();
}
Run Code Online (Sandbox Code Playgroud)

它说"错误:未定义的外部".那是什么意思?在黑暗中刺了一下,我试过了

static inline void do_something(void)
{
  blah;
}

void main(void)
{
  do_something();
}
Run Code Online (Sandbox Code Playgroud)

没有更多的错误.函数定义和对函数的调用都在同一个.c文件中.

有人可以解释为什么一个有效,另一个没有?

(第二个相关问题:如果我想在多个.c文件中使用它们,我在哪里放入内联函数?)

c external inline-functions

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

代码大小:头文件中定义的函数的静态内联与内联

我已经阅读了很多关于在头文件中使用static inlineinline定义函数的文章,以便跨多个翻译单元进行访问.inline由于有外部联系,似乎是正确的方法.

我的问题是inline在.h文件中定义函数时使用说明符导致的结果代码大小:

  • 生成的代码扩展是否inline仍然比引起的更小static inline

  • 为什么extern inline在相应的.c文件中需要声明?

c static inline code-size

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

未使用的“static inline”函数会生成带有“clang”的警告

使用gcc或时clang,启用多个警告通常是一个好主意,第一批警告通常由 提供-Wall。该批次相当大,并且包含特定警告-Wunused-function

现在,-Wunused-function可用于检测static不再调用的函数,这意味着它们无用,因此最好从源代码中删除。当实行“零警告”政策时,它不再是“可取的”,而是彻头彻尾的强制性。

出于性能原因,某些函数可能会直接定义到头文件中*.h,以便可以在编译时内联它们(忽略任何类型的 LTO 魔法)。此类函数通常声明和定义为static inlinestatic inline在过去,此类函数可能会被定义为宏,但只要适用,最好将它们改为函数(没有有趣的类型问题)。

好的,出于性能原因,现在我们将一堆函数直接定义到头文件中。包含此类头文件的单元没有义务使用其所有声明的符号。因此,static inline头文件中定义的函数可能不会被调用。

对于gcc,那很好。gcc会标记一个未使用的static函数,但不会标记一个inline static。但clang结果是不同的:如果单个单元不调用static inline标头中声明的函数,则会触发警告。-Wunused-function而且不需要很多标志就可以到达那里:-Wall就足够了。

解决方法是引入特定于编译器的扩展,例如__attribute__((unused)),它向编译器明确声明标头中定义的函数不一定会被其所有单元调用。好的,但是现在,曾经干净的代码C99包含某种形式的特定编译器扩展,增加了可移植性和维护的重量。

因此,问题更多地是关于这种选择的逻辑:为什么当未调用标头中定义的函数clang时 selects 会触发警告?static inline在什么情况下这是一个好主意?

什么clang建议涵盖头文件中定义的内联函数的相对常见情况,而不要求使用编译器扩展?

编辑:经过进一步调查,问题似乎不正确。使用应用选定列表编译标志(等)的 linter在编辑器(VSCode)中触发警告。但是,当实际使用完全相同的标志列表编译源代码时,不会出现“未使用的函数”警告。clang-Wallclang

到目前为止,编辑器中可见的结果与编译时找到的结果完全相同。这是我第一次目睹差异。

因此,问题似乎与 linter 用于clang生成警告列表的方式有关。这是一个更加复杂和具体的问题。


请注意 …

c c99 clang

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

标签 统计

c ×9

c99 ×3

inline ×3

inline-functions ×3

c++ ×2

static ×2

c-preprocessor ×1

clang ×1

code-size ×1

extern ×1

external ×1

g++ ×1