小编Rob*_*nes的帖子

cscope或ctags为什么选择一个而不是另一个?

我主要使用vim/gvim作为编辑器,并且正在考虑使用lxr(Linux交叉引用)cscopectags的组合来探索内核源代码.但是,我没有使用cscopectags,并且想要听到为什么人们可以选择其中一个而不考虑我使用vim作为主编辑器.

vim kernel ctags cscope

128
推荐指数
2
解决办法
7万
查看次数

具体来说,铸造malloc的结果有什么危险?

现在在人们开始将它标记为dup之前,我已经阅读了以下所有内容,其中没有一个提供我正在寻找的答案:

  1. C FAQ:转换malloc的返回值有什么问题?
  2. SO:我应该显式地转换malloc()的返回值吗?
  3. SO:在C中不必要的指针转换
  4. SO:我是否施放了malloc的结果?

C FAQ和上述问题的许多答案都引用了一个神秘的错误,即铸造malloc的返回值可以隐藏; 但是,它们都没有在实践中给出这种错误的具体例子.现在要注意我说的错误,而不是警告.

现在给出以下代码:

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

int main(int argc, char** argv) {

    char * p = /*(char*)*/malloc(10);
    strcpy(p, "hello");
    printf("%s\n", p);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

用gcc 4.2编译上面的代码,有和没有强制转换都会给出相同的警告,并且程序正确执行并在两种情况下都提供相同的结果.

anon@anon:~/$ gcc -Wextra nostdlib_malloc.c -o nostdlib_malloc
nostdlib_malloc.c: In function ‘main’:
nostdlib_malloc.c:7: warning: incompatible implicit declaration of built-in function ‘malloc’
anon@anon:~/$ ./nostdlib_malloc 
hello
Run Code Online (Sandbox Code Playgroud)

那么,任何人都可以提供一个特定的代码示例,说明由于转换malloc返回值而可能发生的编译或运行时错误,或者这仅仅是一个城市传奇?

编辑我在这个问题上遇到了两个写得很好的论点:

  1. 利于强制转换:CERT建议:立即将内存分配函数调用的结果转换为指向已分配类型的指针
  2. 反对强制转换 (截至2012-02-14的404错误:使用2010-01-27中的互联网归档Wayback Machine副本.{2016-03-18:"由于robots.txt而无法抓取或显示页面."})

c

85
推荐指数
5
解决办法
2万
查看次数

选择Linux I/O调度程序

我读到,通过写入/ sys/block/[disk]/queue/scheduler,可以在运行的内核上更改特定设备的I/O调度程序.例如,我可以在我的系统上看到:

anon@anon:~$ cat /sys/block/sda/queue/scheduler 
noop anticipatory deadline [cfq] 
Run Code Online (Sandbox Code Playgroud)

默认是完全公平的排队调度程序.我想知道的是,在我的自定义内核中包含所有四个调度程序是否有任何用处.除非内核足够智能为正确的硬件选择正确的调度程序,特别是基于闪存的驱动器的"noop"调度程序和传统的其他调度程序之一,似乎编译多个调度程序没有多大意义.硬盘.

是这样的吗?

linux scheduling linux-kernel

81
推荐指数
3
解决办法
14万
查看次数

在C中使用restrict关键字的规则?

我试图了解何时何时不在restrictC中使用关键字以及在什么情况下它提供了实实在在的好处.

在阅读" 揭秘限制关键字 "(提供一些关于使用的经验法则)之后,我得到的印象是,当函数通过指针时,它必须考虑指向的数据可能重叠的可能性(别名)将任何其他参数传递给函数.给定一个功能:

foo(int *a, int *b, int *c, int n) {
    for (int i = 0; i<n; ++i) {
        b[i] = b[i] + c[i];
        a[i] = a[i] + b[i] * c[i];
    } 
}
Run Code Online (Sandbox Code Playgroud)

编译器必须c在第二个表达式中重新加载,因为可能bc指向相同的位置.ba出于同样的原因加载之前,它还必须等待存储.然后它必须等待a存储并且必须重新加载b并且c在下一个循环的开始.如果你这样调用函数:

int a[N];
foo(a, a, a, N);
Run Code Online (Sandbox Code Playgroud)

然后你就可以看到为什么编译器必须这样做了.使用restrict有效地告诉编译器你永远不会这样做,这样它就可以在存储之前丢弃冗余负载c和负载.ab

在另一篇SO帖子中,Nils Pipenbrinck提供了这个场景的工作示例,展示了性能优势.

到目前为止,我已经收集到了一个好主意,使用restrict指针传递给不会内联的函数.显然,如果代码是内联的,编译器可以发现指针不重叠.

现在,这里的事情开始让我变得模糊.

在Ulrich Drepper的论文中," 每个程序员应该了解内存 ",他发表声明称,"除非使用限制,所有指针访问都是混淆的潜在来源",并且他给出了一个子矩阵矩阵的特定代码示例.用途restrict.

但是,当我编写他的示例代码时,无论有没有, …

c memory optimization

68
推荐指数
3
解决办法
2万
查看次数

kernel.h中min宏中"(void)(&_min1 ==&_min2)"的功能是什么?

kernel.h中, min定义为:

#define min(x, y) ({                \
    typeof(x) _min1 = (x);          \
    typeof(y) _min2 = (y);          \
    (void) (&_min1 == &_min2);      \
    _min1 < _min2 ? _min1 : _min2; })
Run Code Online (Sandbox Code Playgroud)

我不明白这行(void) (&_min1 == &_min2);是做什么的.是某种类型检查还是什么?

c linux-kernel

60
推荐指数
4
解决办法
8464
查看次数

Linux内核如何知道在哪里查找驱动程序固件?

我正在Ubuntu下编译一个自定义内核,我遇到了我的内核似乎不知道在哪里寻找固件的问题.在Ubuntu 8.04下,固件与内核版本绑定的方式与驱动程序模块相同.例如,内核2.6.24-24-generic将其内核模块存储在:

/lib/modules/2.6.24-24-generic
Run Code Online (Sandbox Code Playgroud)

及其固件:

/lib/firmware/2.6.24-24-generic
Run Code Online (Sandbox Code Playgroud)

当我根据" 备用构建方法:老式Debian方式 " 编译2.6.24-24通用Ubuntu内核时,我得到了相应的模块目录,除了需要固件的设备外,我的所有设备都工作,例如我的英特尔无线网卡(ipw2200)模块).

内核日志显示,例如,当ipw2200尝试加载固件时,控制固件加载的内核子系统无法找到它:

ipw2200: Detected Intel PRO/Wireless 2200BG Network Connection
ipw2200: ipw2200-bss.fw request_firmware failed: Reason -2
Run Code Online (Sandbox Code Playgroud)

errno-base.h将此定义为:

#define ENOENT       2  /* No such file or directory */
Run Code Online (Sandbox Code Playgroud)

(返回ENOENT的函数在它前面放一个减号.)

我尝试在/ lib/firmware中创建一个符号链接,其中我的内核名称指向2.6.24-24-generic目录,但是这导致了同样的错误.此固件是非GPL,由Intel提供并由Ubuntu打包.我不相信它与特定内核版本有任何实际联系.cmp表明各个目录中的版本是相同的.

那么内核如何知道在哪里寻找固件呢?

更新

我找到了解决我遇到的确切问题的解决方案,但是它不再有效,因为Ubuntu已经淘汰/etc/hotplug.d并且不再存储其固件/usr/lib/hotplug/firmware.

UPDATE2

更多的研究提出了更多的答案.直到版本92 udev,该程序firmware_helper是固件加载的方式.从udev93 开始,这个程序被替换为一个名为firmware.sh的脚本,据我所知,它提供了相同的功能.这两个硬编码固件路径/lib/firmware.Ubuntu似乎仍在使用/lib/udev/firmware_helper二进制文件.

固件文件的名称将传递到firmware_helper环境变量中$FIRMWARE,该变量连接到路径/lib/firmware并用于加载固件.

加载固件的实际请求是由驱动程序(在我的情况下为ipw2200)通过系统调用完成的:

request_firmware(..., "ipw2200-bss.fw", ...);
Run Code Online (Sandbox Code Playgroud)

现在,在驱动程序调用request_firmwarefirmware_helper查看$FIRMWARE …

firmware linux-device-driver linux-kernel

51
推荐指数
2
解决办法
7万
查看次数

在vim中获取ctags以进行定义,而不是声明

我遇到的问题是vim/gvim中的ctags很多时候都会将我带到前向声明而不是函数的实际定义.

有办法解决这个问题吗?

vim ctags

48
推荐指数
3
解决办法
3万
查看次数

restrict关键字是否在gcc/g ++中提供了显着的好处?

有没有人见过任何关于restrictgcc/g ++实际使用C/C++ 关键字的数字/分析是否能在现实中提供任何显着的性能提升(而不仅仅是在理论上)?

我已经阅读了各种推荐/贬低其使用的文章,但我没有碰到任何实际数字,实际上证明了任何一方的论点.

编辑

我知道这restrict不是C++的正式部分,但它得到了一些编译器的支持,我读过Christer Ericson的一篇论文,强烈推荐使用它.

c c++ gcc g++ restrict-qualifier

46
推荐指数
3
解决办法
1万
查看次数

Boost.Test:寻找一个有效的非平凡测试套件示例/教程

如Boost.Test文档和例子并不真的似乎包含我发现任何不平凡的例子,到目前为止,两个教程这里这里同时有帮助都是非常基本的.

我希望为整个项目提供一个主测试套件,同时保持每个模块套件的单元测试和可以独立运行的灯具.我还将使用模拟服务器来测试各种网络边缘情况.

我在使用Ubuntu 8.04,但我会采用Linux或Windows的任何示例,因为我正在编写自己的makefile.

编辑

作为测试,我做了以下事情:

// test1.cpp
#define BOOST_TEST_MODULE Regression
#include <boost/test/included/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(test1_suite)

BOOST_AUTO_TEST_CASE(Test1)
{
    BOOST_CHECK(2 < 1);
}

BOOST_AUTO_TEST_SUITE_END()

// test2.cpp
#include <boost/test/included/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(test2_suite)

BOOST_AUTO_TEST_CASE(Test1)
{
    BOOST_CHECK(1<2);
}

BOOST_AUTO_TEST_SUITE_END()
Run Code Online (Sandbox Code Playgroud)

然后我编译它: g++ test1.cpp test2.cpp -o tests

这给了我关于链接期间的大量"多重定义"错误.

当它在一个文件中时它工作正常.

c++ boost unit-testing tcp mocking

33
推荐指数
2
解决办法
2万
查看次数

关于模拟系统调用的建议

我有一个类调用getaddrinfo进行DNS查找.在测试期间,我想模拟涉及此系统调用的各种错误情况.模拟这样的系统调用的推荐方法是什么?我正在使用Boost.Test进行单元测试.

c++ unit-testing mocking

30
推荐指数
3
解决办法
9708
查看次数