标签: c

Duff的设备如何工作?

我已经在Duff的设备上阅读了维基百科上文章,但是我没理解.我真的很感兴趣,但我已经在那里阅读了几次解释,但我仍然不知道Duff的设备是如何工作的.

更详细的解释是什么?

c duffs-device

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

C中枚举的大小是多少?

我正在创建一组枚举值,但我需要每个枚举值为64位宽.如果我没记错的话,枚举通常与int的大小相同; 但是我认为我读过某个地方(至少在GCC中),编译器可以使枚举成为保持其值所需的任何宽度.那么,有可能有一个64位宽的枚举?

c enums

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

C代码中的错误处理

在C库中以一致的方式处理错误处理错误时,您认为"最佳实践"是什么?

我一直在考虑两种方式:

始终返回错误代码.典型的功能如下所示:

MYAPI_ERROR getObjectSize(MYAPIHandle h, int* returnedSize);
Run Code Online (Sandbox Code Playgroud)

始终提供错误指针方法:

int getObjectSize(MYAPIHandle h, MYAPI_ERROR* returnedError);
Run Code Online (Sandbox Code Playgroud)

使用第一种方法时,可以编写这样的代码,其中错误处理检查直接放在函数调用上:

int size;
if(getObjectSize(h, &size) != MYAPI_SUCCESS) {
  // Error handling
}
Run Code Online (Sandbox Code Playgroud)

这看起来比错误处理代码更好.

MYAPIError error;
int size;
size = getObjectSize(h, &error);
if(error != MYAPI_SUCCESS) {
    // Error handling
}
Run Code Online (Sandbox Code Playgroud)

但是,我认为使用返回值返回数据会使代码更具可读性.很明显,在第二个示例中,某些内容被写入了size变量.

您对我为什么应该选择这些方法或者将它们混合或使用其他方法有任何想法吗?我不是全局错误状态的粉丝,因为它往往会使库的多线程使用更加痛苦.

编辑:只要他们不涉及异常,C++关于此的具体想法也会很有趣,因为目前我不能选择...

c error-handling

138
推荐指数
14
解决办法
9万
查看次数

将objective-c typedef转换为其等效字符串

假设我在.h文件中声明了一个typedef:

typedef enum {
  JSON,
  XML,
  Atom,
  RSS
} FormatType;
Run Code Online (Sandbox Code Playgroud)

我想构建一个将typedef的数值转换为字符串的函数.例如,如果邮件[self toString:JSON]已发送; 它会返回'JSON'.

该函数看起来像这样:

-(NSString *) toString:(FormatType)formatType {
  //need help here
  return [];
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果我尝试这种语法

[self toString:FormatType.JSON];
Run Code Online (Sandbox Code Playgroud)

要将typedef值传递给方法,我收到一个错误.我错过了什么?

c enums typedef objective-c

138
推荐指数
9
解决办法
12万
查看次数

编译时-pthread标志的重要性

在各种多线程C和C++项目中,我看到-pthread标志应用于编译和链接阶段,而其他人根本不使用它,只是传递-lpthread给链接阶段.

有没有危险没有编译和链接-pthread国旗 - 即-pthread实际做什么?我主要对Linux平台感兴趣.

c c++ linux pthreads

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

如何向初学者解释C指针(声明与一元运算符)?

我最近很高兴向C编程初学者解释指针并偶然发现了以下困难.如果你已经知道如何使用指针,它可能看起来似乎不是一个问题,但尝试以清醒的头脑看下面的例子:

int foo = 1;
int *bar = &foo;
printf("%p\n", (void *)&foo);
printf("%i\n", *bar);
Run Code Online (Sandbox Code Playgroud)

对于绝对的初学者来说,输出可能会令人惊讶.在第2行他/她刚刚宣布*bar为&foo,但在第4行结果显示*bar实际上是foo而不是&foo!

您可能会说,混淆源于*符号的模糊性:在第2行中,它用于声明指针.在第4行中,它用作一元运算符,它获取指针指向的值.两件不同的事,对吗?

然而,这种"解释"根本不能帮助初学者.它通过指出一个微妙的差异引入了一个新的概念.这不是教授它的正确方法.

那么,Kernighan和Ritchie是如何解释的呢?

一元运算符*是间接或解除引用运算符; 当应用于指针时,它访问指针指向的对象.[...]

指针ip的声明int *ip用作助记符; 它说表达式*ip是一个int.变量声明的语法模仿可能出现变量的表达式的语法.

int *ip应该读作" *ip会回来int"吗?但是为什么声明后的作业不遵循这种模式?如果初学者想要初始化变量怎么办?int *ip = 1(阅读:*ip将返回a intintis 1)将无法按预期工作.概念模型似乎并不一致.我在这里错过了什么吗?


编辑:它试图在这里总结答案.

c pointers

138
推荐指数
13
解决办法
8862
查看次数

编写程序以应对导致Linux上丢失写入的I/O错误

TL; DR:如果Linux内核丢失了缓冲的I/O写入,那么应用程序是否有任何方法可以找到?

我知道你有fsync()文件(和它的父目录)的耐用性.问题是,如果内核由于I/O错误而丢失了待写入的脏缓冲区,应用程序如何检测并恢复或中止?

想想数据库应用程序等,其中写入顺序和写入持久性可能是至关重要的.

失去写?怎么样?

Linux内核的模块层可以在某些情况下失去缓冲已成功提交的I/O请求write(),pwrite()等等,有这样的错误:

Buffer I/O error on device dm-0, logical block 12345
lost page write due to I/O error on dm-0
Run Code Online (Sandbox Code Playgroud)

(见end_buffer_write_sync(...)end_buffer_async_write(...)fs/buffer.c).

在较新的内核上,错误将包含"丢失的异步页面写入",如:

Buffer I/O error on dev dm-0, logical block 12345, lost async page write
Run Code Online (Sandbox Code Playgroud)

由于应用程序write()已经无错误地返回,因此似乎无法将错误报告给应用程序.

检测它们?

我不熟悉内核源代码,但我认为它设置AS_EIO在缓冲区上,如果它正在执行异步写入,则无法写出:

    set_bit(AS_EIO, &page->mapping->flags);
    set_buffer_write_io_error(bh);
    clear_buffer_uptodate(bh);
    SetPageError(page);
Run Code Online (Sandbox Code Playgroud)

但是我不清楚应用程序是否或如何在以后查找fsync()文件以确认它在磁盘上时会发现这一点.

它看起来像wait_on_page_writeback_range(...) …

c linux posix linux-kernel

138
推荐指数
3
解决办法
9099
查看次数

什么是__stdcall?

我正在学习Win32编程,WinMain原型如下:

int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
Run Code Online (Sandbox Code Playgroud)

我很困惑这个WINAPI标识符的用途和发现:

#define WINAPI      __stdcall
Run Code Online (Sandbox Code Playgroud)

这是做什么的?在返回类型之后,我对此感到困惑.什么是__stdcall?当返回类型和函数名称之间有什么东西时,它是什么意思?

c winapi calling-convention stdcall

137
推荐指数
7
解决办法
10万
查看次数

在Linux中测量时间 - 时间与时钟对比getrusage vs clock_gettime vs gettimeofday vs timespec_get?

其中计时功能,time,clock getrusage,clock_gettime,gettimeofdaytimespec_get,我想清楚地了解它们是如何实现的,为了知道在什么情况下我必须使用他们什么是他们的返回值.

首先,我们需要对返回wall-clock值的函数进行分类,与返回进程或线程值的函数进行比较.gettimeofday返回wall-clock值,clock_gettime返回wall-clock值进程或线程值,具体取决于Clock传递给它的参数.getrusageclock返回过程值.

然后第二个问题涉及这些功能的实施,因此,它们的准确性.这些功能使用哪种硬件或软件机制.

似乎getrusage只使用内核tick(通常为1ms长),因此不能比ms更准确.这样对吗?然后该getimeofday函数似乎使用最准确的底层硬件.因此,它的准确性通常是近期硬件上的微秒(因为API而不能更多).那么clock,手册页谈的是"近似",它是什么意思?那么clock_gettime,API是纳秒级,是否意味着如果底层硬件允许它,它能够如此准确?单调性怎么样?

还有其他功能吗?

c linux time linux-kernel

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

为什么从字符串常量到'char*'的转换在C中有效,但在C++中无效

C++ 11标准(ISO/IEC 14882:2011)在§ C.1.1:

char* p = "abc"; // valid in C, invalid in C++
Run Code Online (Sandbox Code Playgroud)

对于C++来说,没关系,因为指向String Literal的指针是有害的,因为任何修改它的尝试都会导致崩溃.但为什么它在C中有效?

C++ 11还说:

char* p = (char*)"abc"; // OK: cast added
Run Code Online (Sandbox Code Playgroud)

这意味着如果将强制转换添加到第一个语句,它将变为有效.

为什么转换使第二个语句在C++中有效?它与第一个语句有什么不同?它不是仍然有害吗?如果是这样的话,为什么标准说它没关系?

c c++ string char c++11

137
推荐指数
4
解决办法
12万
查看次数