小编ens*_*nsc的帖子

gcc:如何检测错误的“ bool”用法

有什么方法可以检测bool代码中值的错误使用,例如

#include <stdbool.h>

void *foo(void)
{
    return false;
}

int bar(void)
{
    return true;
}
Run Code Online (Sandbox Code Playgroud)

gcc(8.3.1)和clang(7.0.1)均接受两个功能,而没有任何警告

$ gcc -Wall -W -pedantic -c x.c
$ clang -Xclang -analyzer-checker=alpha --analyze  -Wall -W -pedantic -c x.c
$ clang -Wall -W -pedantic -c x.c
$
Run Code Online (Sandbox Code Playgroud)

编译为C ++代码可以检测到该问题,foo()但这不是一种选择,但是其余代码是C,而不是C ++。

是否还有其他(-W)选项或开关可为这些情况创建诊断?

c gcc static-analysis clang

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

clang-analyze:如何避免出现“垃圾价值”警告?

检查时

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char    c[20];
    size_t  l;

    l = fread(c, sizeof c, 1, stdin);
    if (l != 1)
        return 1;

    return c[0] == 42;
}
Run Code Online (Sandbox Code Playgroud)

用c,我得到

$ clang  --analyze -Xclang -analyzer-checker=alpha x.c
x.c:13:14: warning: The left operand of '==' is a garbage value
        return c[0] == 42;
               ~~~~ ^

$ clang -v
clang version 7.0.1 (Fedora 7.0.1-4.fc29)
Run Code Online (Sandbox Code Playgroud)

此时真的有机会c包含垃圾吗?如果没有,如何避免发出警告(没有对进行明显的初始化c)?

更新资料

因为这似乎是一个普遍的共识,那就是错误的肯定,所以我想集中讨论如何避免警告。

的确,这fread()是一个标准功能,分析人员应该在执行操作时就memset()已经知道了它们的语义。但是我对更通用的方法感兴趣,例如可以在库函数上使用。

我会assert_defined()以类似的方式调用一些特殊功能(让它调用它)

    l = fread(c, …
Run Code Online (Sandbox Code Playgroud)

c false-positive fread clang-static-analyzer garbage

7
推荐指数
1
解决办法
159
查看次数

实现 `std::marker::Unpin` 是否安全?

我即将将一些代码从 futures-0.1 转换为 futures-0.3,其中poll()方法现在需要固定数据。我的一些结构是不可固定的,这使移植变得复杂。但是似乎存在通过impl Unpin为这些类添加一个的简单方法。这安全吗?有哪些替代方案?

示例代码:

extern crate futures;

use std::future::Future;
use std::pin::Pin;
use std::task::{ Poll, Context };

struct InnerData {
    _pin: std::marker::PhantomPinned,
}

struct Stream {
}

struct Poller {
    _data: InnerData,
    file: Stream,
}

impl futures::stream::Stream for Stream {
    type Item = ();

    fn poll_next(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Option<Self::Item>> {
        Poll::Pending
    }
}

impl Future for Poller {
    type Output = Result<(), ()>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context) -> …
Run Code Online (Sandbox Code Playgroud)

future rust

7
推荐指数
1
解决办法
1014
查看次数

gcc内联ARM程序集中的`ldm/stm`

我正在尝试使用内联汇编创建ldm(resp.stm)指令,但是在表达操作数​​方面存在问题(尤其是:它们的顺序).

一件微不足道的事

void *ptr;
unsigned int a;
unsigned int b;

__asm__("ldm %0!,{%1,%2}" : "+&r"(ptr), "=r"(a), "=r"(b));
Run Code Online (Sandbox Code Playgroud)

不工作,因为它可能把ar1br0:

ldm ip!, {r1, r0}
Run Code Online (Sandbox Code Playgroud)

ldm期望寄存器按升序排列(因为它们在位域中编码)所以我需要一种方法来说明用于的寄存器a低于此b.

一个简单的方法是固定分配寄存器:

register unsigned int a asm("r0");
register unsigned int b asm("r1");

__asm__("ldm %0!,{%1,%2}" : "+&r"(ptr), "=r"(a), "=r"(b));
Run Code Online (Sandbox Code Playgroud)

但这会消除很多灵活性,并可能使生成的代码不是最佳的.

gcc(4.8)是否支持特殊约束ldm/stm?或者,有更好的方法来解决这个问题(例如某些__builtin功能)?

编辑:

因为有建议使用"更高级别"的结构......我想要解决的问题是32位32位字的打包(例如输入是8个字,输出是5个字).伪代码是

asm("ldm  %[in]!,{ %[a],%[b],%[c],%[d] }" ...)
asm("ldm  %[in]!,{ %[e],%[f],%[g],%[h] }" ...) /* splitting of ldm generates better …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc arm inline-assembly

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