小编P.P*_*.P.的帖子

与GCC 5.4.0的一次昂贵的跳跃

我有一个看起来像这样的功能(只显示重要部分):

double CompareShifted(const std::vector<uint16_t>& l, const std::vector<uint16_t> &curr, int shift, int shiftY)  {
...
  for(std::size_t i=std::max(0,-shift);i<max;i++) {
     if ((curr[i] < 479) && (l[i + shift] < 479)) {
       nontopOverlap++;
     }
     ...
  }
...
}
Run Code Online (Sandbox Code Playgroud)

写得这样,我的机器上的功能耗时约34ms.将条件更改为bool乘法后(使代码看起来像这样):

double CompareShifted(const std::vector<uint16_t>& l, const std::vector<uint16_t> &curr, int shift, int shiftY)  {
...
  for(std::size_t i=std::max(0,-shift);i<max;i++) {
     if ((curr[i] < 479) * (l[i + shift] < 479)) {
       nontopOverlap++;
     }
     ...
  }
...
}
Run Code Online (Sandbox Code Playgroud)

执行时间减少到~19ms.

使用的编译器是带有-O3的GCC 5.4.0,在使用godbolt.org检查生成的asm代码后,我发现第一个示例生成跳转,而第二个示例没有生成跳转.我决定尝试GCC 6.2.0,它在使用第一个例子时也生成一个跳转指令,但GCC 7似乎不再生成一个.

找到这种加速代码的方式是相当可怕的,花了很长时间.为什么编译器会以这种方式运行?这是程序员应该注意的吗?还有更类似的东西吗?

编辑:链接到godbolt https://godbolt.org/g/5lKPF3

c++ gcc

171
推荐指数
3
解决办法
9563
查看次数

为什么Math.pow(0,0)=== 1?

我们都知道0 0是不确定的.

但是,javascript说:

Math.pow(0, 0) === 1 // true
Run Code Online (Sandbox Code Playgroud)

C++说同样的话:

pow(0, 0) == 1 // true
Run Code Online (Sandbox Code Playgroud)

为什么?

我知道:

>Math.pow(0.001, 0.001)
0.9931160484209338
Run Code Online (Sandbox Code Playgroud)

但为什么不Math.pow(0, 0)抛出错误呢?或者也许NaN会比...更好1.

javascript c++ language-agnostic pow

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

替代for循环语法

下面是C标准的片段(n1256 TC3 C99的第6.8.5节).

iteration-statement:
    while ( 表达式 ) 语句
    do 语句 while ( 表达式 ) ;
    对于 ( 表达选择 ; 表达选择 ; 表达选择 ) 声明
     ( 声明 表达选择 ; 表达选择 ) 语句

引起我兴趣的是最后的陈述:for ( declaration expression ; expression ) statement.6.8.5.1解释了for循环,但只提到了for ( clause-1 ; expression-2 ; expression-3 ) statement语法.

我根据这种语法尝试编写代码,但是它们都给了我语法错误.例子:

for (int i = 0, i; i++) { /* ... */ }
for (int …
Run Code Online (Sandbox Code Playgroud)

c for-loop language-lawyer

34
推荐指数
2
解决办法
3911
查看次数

如何在C中打印内存地址

我的代码是:

#include <stdio.h>
#include <string.h>

void main()
    {
    char string[10];
    int A = -73;
    unsigned int B = 31337;

    strcpy(string, "sample");

    // printing with different formats
    printf("[A] Dec: %d, Hex: %x, Unsigned: %u\n", A,A,A);
    printf("[B] Dec: %d, Hex: %x, Unsigned: %u\n", B,B,B);
    printf("[field width on B] 3: '%3u', 10: '%10u', '%08u'\n", B,B,B);

    // Example of unary address operator (dereferencing) and a %x
    // format string 
    printf("variable A is at address: %08x\n", &A);
Run Code Online (Sandbox Code Playgroud)

我在linux mint中使用终端编译,当我尝试使用gcc编译时,我收到以下错误消息:

basicStringFormatting.c: In function ‘main’:
basicStringFormatting.c:18:2: warning: …
Run Code Online (Sandbox Code Playgroud)

c printf pointers memory-address unary-operator

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

是否在一个变量上使用sizeof,其中存在一个同名的类型?

这是明确定义的行为还是未定义/以其他方式定义哪些foo(数据类型或标识符)sizeof将在哪些操作?

typedef int foo;

int main(int argc, char *argv[])
{
    char foo;
    printf ("%u\r\n", sizeof(foo));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果它定义得很好,有没有办法可以获得数据类型的大小foo而不声明该类型的变量只sizeof在其上使用?

c sizeof undefined-behavior

13
推荐指数
3
解决办法
709
查看次数

什么注册 const char *const *name; 意思是为什么这个变量在函数之外?

void
usage (cpp)
    register const char *const *cpp;
{
    (void) fprintf (stderr, *cpp++, program_name, cvs_cmd_name);
    for (; *cpp; cpp++)
    (void) fprintf (stderr, *cpp);
    error_exit ();
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么 register 变量不在大括号内,fprintf 前面的这个 (void) 是什么?还要注册 const char *const *cpp,我以前从未见过这样的事情

c

10
推荐指数
2
解决办法
241
查看次数

Java在构造函数中设置私有字段

常见的设计实践是将实例变量设为私有,并让公共getter和setter访问它们.但很多时候,我在互联网上看到了具有构造函数的代码示例,这些构造函数将值直接分配给私有实例变量,而不是使用构造函数内部的setter.我错过了什么吗?

public class Person{
    private String name;

    public Person(String name){
        //is this right, seems like the whole encapsulation purpose is defeated
        this.name = name;

        //shouldn't this be used
        setName(name);
    }

    public String getName(){
        return this.name;
    }

    public void setName(String name){
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

java constructor private-members

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

为什么使用(;;)?

我见过代码(在C中),其中包含类似于:

for(;;){
}
Run Code Online (Sandbox Code Playgroud)

这将如何工作,为什么它在任何情况下使用?

c for-loop

6
推荐指数
4
解决办法
767
查看次数

以下链式赋值是否会导致未定义的行为?

以下代码是否调用未定义的行为C

int a = 1, b = 2;
a = b = (a + 1);
Run Code Online (Sandbox Code Playgroud)

我知道以下内容调用UB:

a = b = a++;
Run Code Online (Sandbox Code Playgroud)

原因是它违反了标准中的以下条款:

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算来修改一次.此外,只能访问先前值以确定要存储的值.

但是,第一个代码段不违反此条款.一位同事说这种说法a = b = a+1也可能意味着

a = a + 1;
b = a + 1;
Run Code Online (Sandbox Code Playgroud)

要么

b = a + 1;
a = b;
Run Code Online (Sandbox Code Playgroud)

我认为,由于"从右到左"的相关性=,它总是必须意味着a = (b = (a+1)),而不是

a = a + 1;
b = a + 1;
Run Code Online (Sandbox Code Playgroud)

不过,我并不积极.是UB吗?

c undefined-behavior

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

C中的重入和重入?

我正在读一本名为Linux System Programming的书.引用本书:

那么系统调用和其他库函数呢?如果您的进程正在写入文件或分配内存,并且信号处理程序写入同一文件或调用malloc(),该怎么办?有些功能显然不可重入.如果一个程序正在执行一个非重入函数并且信号发生并且信号处理程序然后调用相同的非重合函数,则可能发生混乱.

但接下来会:

保证重入函数

保证可以安全重入的功能用于信号

一些功能在这里..

写()

一些功能在这里..

我很困惑,是可以write()折返的,还是没有?因为我认为它与声明冲突:

如果您的进程正在写入文件,该怎么办?

c concurrency reentrancy

6
推荐指数
2
解决办法
907
查看次数