当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?
在可执行文件的哪个段(.BSS,.DATA,其他)中存储了静态变量,以便它们没有名称冲突?例如:
foo.c: bar.c:
static int foo = 1; static int foo = 10;
void fooTest() { void barTest() {
static int bar = 2; static int bar = 20;
foo++; foo++;
bar++; bar++;
printf("%d,%d", foo, bar); printf("%d, %d", foo, bar);
} }
Run Code Online (Sandbox Code Playgroud)
如果我编译两个文件并将其链接到重复调用fooTest()和barTest的main,则printf语句将独立增加.有意义,因为foo和bar变量是翻译单元的本地变量.
但是存储分配在哪里?
需要明确的是,假设您有一个工具链可以输出ELF格式的文件.因此,我相信,有有将一些空间,对于那些静态变量的可执行文件保留.
出于讨论目的,我们假设我们使用GCC工具链.
我们需要在C中实现一个简单的状态机.
标准的switch语句是最好的方法吗?
我们有一个当前状态(状态)和转换触发器.
switch(state)
{
case STATE_1:
state = DoState1(transition);
break;
case STATE_2:
state = DoState2(transition);
break;
}
...
DoState2(int transition)
{
// Do State Work
...
if(transition == FROM_STATE_2) {
// New state when doing STATE 2 -> STATE 2
}
if(transition == FROM_STATE_1) {
// New State when moving STATE 1 -> STATE 2
}
return new_state;
}
Run Code Online (Sandbox Code Playgroud)
对于简单的状态机是否有更好的方法
编辑:对于C++,我认为Boost Statechart库可能是要走的路.但是,它对C 没有帮助.让我们专注于C用例.
C语言中未指定行为的一个示例是评估函数参数的顺序.它可能是左右或左右,你只是不知道.这会影响评估方式foo(c++, c)或foo(++c, c)得到评估.
还有什么其他未指明的行为可以让不知情的程序员感到惊讶?
可能重复:
C,C++,Java和C#中的前后增量运算符行为
这是一个测试用例:
void foo(int i, int j)
{
printf("%d %d", i, j);
}
...
test = 0;
foo(test++, test);
Run Code Online (Sandbox Code Playgroud)
我希望得到一个"0 1"输出,但我得到"0 0"什么给了??
在大多数C或C++环境中,存在"调试"模式和"释放"模式编译.
看看两者之间的区别,您会发现调试模式添加了调试符号(通常是许多编译器上的-g选项),但它也会禁用大多数优化.
在"发布"模式下,您通常会启用各种优化.
为什么不同?
在多任务操作系统环境中,有时您会听到术语循环调度.它指的是什么?
那还有什么其他的安排?
我已经进入嵌入式领域一段时间了,似乎我与之交谈的大多数程序员似乎都在做与15年或更久前相同的事情:Waterfall(ish)开发,命令行工具一小群人使用棉绒.
将其与服务器/桌面环境进行对比,其中似乎有许多与编程的各种方面相关的活动:
只是嵌入式环境使实施新实践或工具变得更加困难吗?
是嵌入式程序员的思维方式让他们远离新的工具/概念吗?
与IT专注领域相比,典型嵌入式行业的管理是否落后于曲线?
我确实认识到这是一种概括,一些嵌入式项目确实使用了Scrum,Agile,CI,Automated Builds(实际上我在一家自80年代开始实施的公司工作).但我的印象是它只是一个很小的比例.
在嵌入式应用程序中,我们有一个表格,描述了在目标板上有效的各种地址范围.该表用于设置MMU.
RAM地址范围标记为可缓存,但其他区域标记为不可缓存.这是为什么?
c ×7
c++ ×3
embedded ×2
caching ×1
memory ×1
methodology ×1
scheduler ×1
trampolines ×1
type-punning ×1