我有一个看起来像这样的功能(只显示重要部分):
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
我们都知道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.
下面是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) 我的代码是:
#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) 这是明确定义的行为还是未定义/以其他方式定义哪些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在其上使用?
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,我以前从未见过这样的事情
常见的设计实践是将实例变量设为私有,并让公共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) 以下代码是否调用未定义的行为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吗?
我正在读一本名为Linux System Programming的书.引用本书:
那么系统调用和其他库函数呢?如果您的进程正在写入文件或分配内存,并且信号处理程序写入同一文件或调用malloc(),该怎么办?有些功能显然不可重入.如果一个程序正在执行一个非重入函数并且信号发生并且信号处理程序然后调用相同的非重合函数,则可能发生混乱.
但接下来会:
保证重入函数
保证可以安全重入的功能用于信号
一些功能在这里..
写()
一些功能在这里..
我很困惑,是可以write()折返的,还是没有?因为我认为它与声明冲突:
如果您的进程正在写入文件,该怎么办?
c ×7
c++ ×2
for-loop ×2
concurrency ×1
constructor ×1
gcc ×1
java ×1
javascript ×1
pointers ×1
pow ×1
printf ×1
reentrancy ×1
sizeof ×1