这对我来说是一个真正的WTF,看起来像GCC中的一个错误,但我想让社区看一看并为我找到解决方案.
这是我能想到的最简单的程序:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint16_t i = 1;
uint16_t j = 2;
i += j;
return i;
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用-Werror=conversion标志在GCC上编译它,我正在使用我的大部分代码.
这是结果:
.code.tio.c: In function ‘main’:
.code.tio.c:9:7: error: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
i += j;
Run Code Online (Sandbox Code Playgroud)
此代码会发生同样的错误:
uint16_t i = 1;
i += ((uint16_t)3);
Run Code Online (Sandbox Code Playgroud)
错误是
.code.tio.c: In function ‘main’:
.code.tio.c:7:7: error: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
i …Run Code Online (Sandbox Code Playgroud) 假设我有一个表达式,其中只有一部分是不太可能的,但另一个是统计中性的:
if (could_be || very_improbable) {
DoSomething();
}
Run Code Online (Sandbox Code Playgroud)
如果我将非常不可能的位放在unlikely()宏中,它会以任何方式帮助编译器吗?
if (could_be || unlikely(very_improbable)) {
DoSomething();
}
Run Code Online (Sandbox Code Playgroud)
注意:我不是在问马科斯是如何工作的 - 我理解这一点.这里的问题是关于GCC,如果我只暗示其中的一部分,它是否能够优化表达式.我也认识到它可能在很大程度上取决于所讨论的表达方式 - 我对那些有这些宏经验的人很有吸引力.
我发现Python中的一个行为让我感到困惑和烦恼,我想知道我的错误.
我有一个函数应该采用任意数量的参数和关键字,但另外应该有一些默认值关键字,包括它的实际接口:
def foo(my_keyword0 = None, my_keyword1 = 'default', *args, **kws):
for argument in args:
print argument
Run Code Online (Sandbox Code Playgroud)
问题是,如果我尝试调用foo(1, 2, 3)我将只获得3的打印输出,值1和2将覆盖我的关键字参数.
另一方面,如果我尝试在之后*args或之后移动我的关键字**kws会导致语法错误.我发现问题的唯一解决方案是从中提取关键字参数**kws并为其设置默认值:
def foo(*args, **kws):
my_keyword0 = None if 'my_keyword0' not in kws else kws.pop('my_keyword0')
my_keyword0 = 'default' if 'my_keyword1' not in kws else kws.pop('my_keyword1')
for argument in args:
print argument
Run Code Online (Sandbox Code Playgroud)
这很糟糕,因为它迫使我添加无意义的代码,因为函数签名变得难以理解 - 你必须实际读取函数代码而不是仅仅查看它的接口.
我错过了什么?有没有更好的方法来做到这一点?
我遇到过一种情况,我正在处理一段代码,我命令对远程对象进行更改(这是我无法复制以克服一个克隆),然后请求远程对象进行某些操作.新状态并通过一系列相反的命令恢复我对它所做的所有更改.问题是,如果在所有这些更改的中间我遇到错误,我希望能够回滚到目前为止所做的所有更改.
我想到的最合适的解决方案是python try-finally工作流程,但是当命令序列很长时,这是相当有问题的:
try:
# perform action
try:
# perform action
try:
# ...
finally:
# unroll
finally:
# unroll
finally:
# unroll
Run Code Online (Sandbox Code Playgroud)
这样,我需要的命令越多,我的缩进和嵌套就越深入,代码的可读性就越少.我已经考虑过其他一些解决方案,比如维护一个堆栈,每个命令都会推送回滚动作,但这可能会变得相当复杂,我不喜欢将绑定方法推入堆栈.我还考虑为我执行的每个操作递增一个计数器然后在一个单独的最终根据计数器决定我想要的回滚类型,但同样,这些代码的可维护性变得很痛苦.
我搜索"交易"和"回滚"的大多数点击都与数据库相关,并且不太适合更通用的代码......任何人都对如何系统地压扁这种暴行有一个好主意?