小编mrn*_*mrn的帖子

C编译器是否有义务始终从内存重新加载const值?

const我的嵌入式C程序中有一个变量.它0在程序代码中定义和初始化.它通过链接描述文件放在一个特殊的ROM区域.可以通过特殊编程程序更改特殊区域的内容,但在主程序执行期间不能更改.

问题是我是否必须将常数声明为volatile.如果它没有标记为volatile,编译器是否允许用它替换所有引用0?或者是否有义务在程序执行期间至少加载一次?

c

24
推荐指数
2
解决办法
1507
查看次数

C和C++中的编译器优化和临时分配

请参阅以下在C和C++中有效的代码:

extern int output;
extern int input;
extern int error_flag;

void func(void)
{
  if (0 != error_flag)
  {
    output = -1;
  }
  else
  {
    output = input;
  }
}
Run Code Online (Sandbox Code Playgroud)
  1. 是否允许编译器以与下面类似的方式编译上述代码?

    extern int output;
    extern int input;
    extern int error_flag;
    
    void func(void)
    {
      output = -1;
      if (0 == error_flag)
      {
        output = input;
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    换句话说,被编译器允许生成(从第一个片段)的代码,总是让-1到一个临时分配output,然后分配input值,以output根据error_flag状态?

  2. 如果output将被声明为volatile ,编译器是否会被允许这样做?

  3. 如果output声明为atomic_int(stdatomic.h),是否允许编译器执行此操作?

大卫施瓦茨评论后更新:

如果编译器可以自由地向变量添加额外的写入,则似乎无法从C代码中判断是否存在数据争用.怎么判断这个?

c c++ embedded concurrency

10
推荐指数
1
解决办法
574
查看次数

不受保护的共享变量访问是否始终是数据竞争?

假设x是一个共享的线程间变量而func总是返回0,那么下面的代码是否包含C11和C++ 11的数据竞争?请假设x是用两个不同的线程写入的,除了下面的switch语句外,总是有一个正确的锁.

int x; // global variable

...

int y; // local variable

...

switch (func())
{
  case 1:
  {
    x = 0;
    y = 1;
    break;
  }
  case 2:
  {
    x = 0;
    y = 2;
    break;
  }
  case 3:
  default:
  {
    y = 3;
    break;
  }
}
Run Code Online (Sandbox Code Playgroud)

标准中有一个注释(C11和C++ 11),它排除了向代码引入数据争用的编译器转换.是否允许编译器转换代码如下所示?下面的代码肯定包含一个数据竞争,但问题是编译器是否已经引入它或者它是否已经在原始代码中.虽然无法访问,但是对共享变量进行了不受保护的访问.

int x; // global variable

...

int y; // local variable

...

temp = x;
x = 0;
switch (func())
{
  case 1:
  {
    y = 1;
    break;
  } …
Run Code Online (Sandbox Code Playgroud)

c c++ multithreading c++11 c11

5
推荐指数
1
解决办法
383
查看次数

如何理解独立式C或C++实现中的原子?

C11和C++ 11根据执行线程定义原子.而在托管环境中,很清楚线程是什么,在独立式语言实现中它是一个模糊的术语.

  1. 如何在独立实现中正式理解C11和C++ 11中指定的原子,其中所有线程必须在程序内实现?例如:ISR是一个单独的执行线程吗?
  2. 为什么标准委员会根据线程而不是简单地在代码排序领域定义原子?
  3. 除了gcc之外,还有哪些嵌入式编译器已经支持C11/C++ 11原子?

c c++ c++11 c11

5
推荐指数
1
解决办法
279
查看次数

C 编译器是否有义务在内存中放置一个静态常量?

C 编译器是否有义务在内存中放置一个静态常量变量,或者是否允许在引用时将其用作立即指令操作数?

c c++

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

linux内核如何在用户模式和内核模式堆栈之间切换?

当系统调用或中断出现时,linux内核如何在用户模式和内核模式堆栈之间切换?我的意思是确切的机制是什么 - 用户模式堆栈指针会发生什么以及内核模式堆栈指针来自哪里?什么由硬件完成,什么必须由软件完成?

linux linux-kernel

2
推荐指数
1
解决办法
1268
查看次数

C/C++:预处理器指令应如何处理宏参数列表?

C 和 C++ 标准都指定了以下内容:

\n
\n

16.3.1 参数替换 (C++11)

\n

6.10.3.1 参数替换 (C11)

\n

在识别出调用类似函数的宏的参数后,将进行参数替换。替换列表中的参数,除非前面有 # 或 ## 预处理标记或后面有 ## 预处理标记(见下文),否则在其中包含的所有宏都已展开后将被相应的参数替换。在被替换之前,每个参数\xe2\x80\x99s预处理标记被完全宏替换,就好像它们形成了预处理文件的其余部分一样;没有其他可用的预处理标记。

\n
\n

人们可以将本段解释为标准要求:

\n

(1) 首先识别宏参数(以逗号分隔),然后分别展开每个参数中包含的所有宏,

\n

或者

\n

(2) 展开参数列表中包含的所有宏,然后识别每个参数。

\n

为了说明这一点,让我们考虑以下示例代码:

\n
#define CONDITION (0)\n\n#if (CONDITION > 0)\n#define FunctionAlias(par_a, par_b, par_opt, par_c) \\\n          FunctionName(par_a, par_b, par_opt, par_c)\n#else\n#define FunctionAlias(par_a, par_b, par_c) \\\n          FunctionName(par_a, par_b, par_c)\n#endif\n\nint global_a, global_b, global_c;\n#if (CONDITION > 0)\nint global_opt;\n#endif\n\nvoid FunctionName(int a, int b, int c)\n{\n}\n \nvoid AnotherFunction()\n{\n   FunctionAlias(\n                  global_a,\n                  global_b,\n                  #if (CONDITION > 0)\n                  global_opt,\n …
Run Code Online (Sandbox Code Playgroud)

c c++ standards preprocessor c-preprocessor

2
推荐指数
1
解决办法
894
查看次数