我正在 Ubuntu 17.04 中编写一个简单的内核模块,它接受一个字符串并将其打印在内核日志中。
#include<linux/module.h>
#include<linux/init.h>
#include<linux/moduleparam.h>
char* mystring = "hello world";
module_param(mystring ,charp ,S_IRUSR | S_IWUSR);
void display(void){
printk(KERN_ALERT "%s" ,mystring);
}
static int hello(void){
//printk(KERN_ALERT "hello module");
display();
return 0;
}
static void bye(void){
printk(KERN_ALERT "bye");
}
module_init(hello);
module_exit(bye);
Run Code Online (Sandbox Code Playgroud)
我运行命令make,然后当我运行时insmod test.ko mystring="blahblahblah",模块将被正确插入,但是当我运行时dmesg它不显示blahblahblah.
在我运行之后rmmod test.ko,dmseg该表达式blahblahblah将出现在终端中。当我运行insmod test.ko mystring="blahblahblah"一次,然后dmesg在blahblahblah将被打印出来。
究竟是什么问题?是我的问题还是系统的问题?
我有一个结构用于构建控制板的消息我需要保持C167 16位Keil编译器和32位Tricore gcc编译器之间的软件兼容性.
typedef struct
{
unsigned char new_weld_status[2];
UINT32 new_weld_count;
UINT16 new_weld_fail_count;
} NEW_PULSE_DATA;
Run Code Online (Sandbox Code Playgroud)
该数组new_weld_status[2]在16位编译器上占用2个字节,在32位编译器上占用4个字节.我正在考虑new_weld_status[2]用gcc编译时替换所有的联合.但是有一个我可以用于gcc的开关,使chars适合/对齐2个字节?
谢谢
ODR允许我们多次定义相同的内联函数(有一些限制)。
但是,简单的static函数情况又如何呢?
// First TU
static int foo() { return 0; }
int bar1() { return foo(); }
// Second TU
static int foo() { return 1; }
int bar2() { return foo(); }
Run Code Online (Sandbox Code Playgroud)
如果我们快速阅读[basic.def.odr] p4,我们可以天真的得出结论,那就是UB:
每个程序应准确地包含在该程序中被丢弃的语句之外的每个非内联函数或变量的一个定义(9.4.1);无需诊断。
在C ++标准中哪里指定了每个foo函数都是不同的函数,因此即使它们具有相同的名称,也不会破坏ODR?
仅仅是阅读[basic.link] p2.2的问题(即,由于内部链接,名称不指向同一实体,因此[basic.def.odr] p4在这里不适用)?还是做出决定时涉及更多细微差别/规则(例如[basic.scope]中的内容)?
请注意,使用未命名的名称空间,结果很明显,因为名称已经是不同的/唯一的。
我目前对 C 结构信息隐藏的概念有点困惑。
这道题的背景是一个嵌入式c项目,对OOP的了解几乎为零。
到目前为止,我总是在相应模块的头文件中声明我的 typedef 结构。因此每个想要使用该结构的模块都知道该结构类型。
但经过 MISRA-C 检查后,我发现了中等严重性警告:MISRAC2012-Dir-4.8 - 结构的实现不必要地暴露给翻译单元。
经过一番研究后,我通过限制结构成员对私有范围的可见访问,发现了 C 结构信息隐藏的概念。
我立即尝试了一个简单的例子,如下所示:
struct_test.h
//struct _structName;
typedef struct _structName structType_t;
Run Code Online (Sandbox Code Playgroud)
struct_test.c
#include "struct_test.h"
typedef struct _structName
{
int varA;
int varB;
char varC;
}structType_t;
Run Code Online (Sandbox Code Playgroud)
主程序
#include "struct_test.h"
structType_t myTest;
myTest.varA = 0;
myTest.varB = 1;
myTest.varC = 'c';
Run Code Online (Sandbox Code Playgroud)
这会产生编译器错误,即对于 main.c,myTest 的大小未知。当然是这样,main.c 只知道 structType_t 类型的结构存在,而没有其他信息。
所以我继续研究并偶然发现了不透明指针的概念。
所以我尝试了第二次尝试:
struct_test.h
typedef struct _structName *myStruct_t;
Run Code Online (Sandbox Code Playgroud)
struct_test.c
#include "struct_test.h"
typedef struct _structName
{
int varA;
int varB;
char varC;
}structType_t;
Run Code Online (Sandbox Code Playgroud)
主程序
#include …Run Code Online (Sandbox Code Playgroud) 假设我有这门课
class Point
{
inline float x() const { return v[0]; }
inline float y() const { return v[1]; }
inline float z() const { return v[2]; }
float v[3];
};
Run Code Online (Sandbox Code Playgroud)
我这样做:
Point myPoint;
myPoint[0] = 5;
// unrelated code goes here
float myVal = myPoint.x() + 5;
Run Code Online (Sandbox Code Playgroud)
将上的GCC-O2或-O3优化掉任何调用x()与刚开v[0]?IE:
float myVal = myPoint.v[0] + 5;
Run Code Online (Sandbox Code Playgroud)
或者有什么理由说明这是不可能的?
更新:应该提到我确实意识到inline对编译器的建议比其他任何事情都重要,但无论如何都想知道。
作为一个附加问题,对此类进行模板化是否会对可以进行的优化产生任何影响?
我正在尝试将打包的数据结构写出到二进制文件中,但是正如您从od -x下面看到的那样,结果的顺序并不符合预期。我在 64 位 Intel 系统上使用 gcc。有谁知道为什么顺序是错误的?它看起来不像字节序问题。
#include <stdio.h>
#include <stdlib.h>
struct B {
char a;
int b;
char c;
short d;
} __attribute__ ((packed));
int main(int argc, char *argv[])
{
FILE *fp;
fp = fopen("temp.bin", "w");
struct B b = {'a', 0xA5A5, 'b', 0xFF};
if (fwrite(&b, sizeof(b), 1, fp) != 1)
printf("Error fwrite\n");
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
ASCII 61 是'a',所以b.a成员。ASCII 62 是'b',所以b.c成员。奇怪的0xA5A5是如何在序列中展开。
$ od -x temp.bin
0000000 a561 00a5 …Run Code Online (Sandbox Code Playgroud) 例如,下面是一条 X86-64 指令:
movq (%rdi),%rdi
Run Code Online (Sandbox Code Playgroud)
它读取内容(由 指向%rdi)并将此内容设置为%rdi,这在时序逻辑中是否有效?
或者我们是否必须将其分配给不同的寄存器并将其移回:
movq (%rdi), %rsi
movq rsi, %rdi
Run Code Online (Sandbox Code Playgroud) 我已经将这两种数据结构定义为类型:
typedef struct {
float x,y,z;
} location3d;
typedef struct {
location3d location;
float radius;
} particle3d;
Run Code Online (Sandbox Code Playgroud)
我的问题是:我可以创建一个常量location3d还是一个常量particle3d?我搜索了常量,但我发现的只是如何定义常量整数或chars... 等。
因此,一旦std::pair初始化了至少一个引用变量,例如像这样:
int a = 53;
int b = 42;
std::pair<int, int&> foo(33, a);
Run Code Online (Sandbox Code Playgroud)
有没有办法改变引用变量的指向?
任务:
foo = std::make_pair(33, std::ref(b));
Run Code Online (Sandbox Code Playgroud)
和交换:
std::pair<int, int&> bar(33, b);
foo.swap(bar);
Run Code Online (Sandbox Code Playgroud)
似乎只是将新内容移动到a并留下foo指向它之前 ( a)位置的第二个成员,因此没有做我在这里试图实现的目标。我知道引用不能像这里回答的那样反弹
,但这不是我在这里想要做的。我想要做的是制作一对新的并将其内容分配给现有的,这在技术上不是一回事。
提前致谢!