Tag: 转换

转换为uint64时,int32或32位指针的意外符号扩展

我使用Visual Studio 2010( cl.exe /W4 )将此代码编译为C文件: int main( int argc, char *argv[] ) { unsigned __int64 a = 0x00000000FFFFFFFF; void *orig = (void *)0xFFFFFFFF; unsigned __int64 b = (unsigned __int64)orig; if( a != b ) printf( ” problem\ta: %016I64X\tb: %016I64X\n”, a, b ); return; } 没有警告,结果是: 问题a:00000000FFFFFFFF b:FFFFFFFFFFFFFFFF 我想int orig = (int)0xFFFFFFFF会引起争议,因为我没有指定一个整数的指针。 但结果是一样的。 有人可以向我解释在C标准中它覆盖了orig是从0xFFFFFFFF扩展到0xFFFFFFFFFFFFFFFF的符号吗? 我原以为(unsigned […]

如果我转换函数指针,改变参数的数量会发生什么

我刚刚开始围绕C中的函数指针。要了解函数指针的转换是如何工作的,我编写了以下程序。 它基本上创建了一个函数指针,该函数指向一个带有一个参数的函数,将它转换为带有三个参数的函数指针,并调用该函数,提供三个参数。 我很好奇会发生什么: #include int square(int val){ return val*val; } void printit(void* ptr){ int (*fptr)(int,int,int) = (int (*)(int,int,int)) (ptr); printf(“Call function with parameters 2,4,8.\n”); printf(“Result: %d\n”, fptr(2,4,8)); } int main(void) { printit(square); return 0; } 这编译并运行时没有错误或警告(在Linux / x86上为gcc -Wall)。 我系统的输出是: Call function with parameters 2,4,8. Result: 4 显然,多余的论点只是默默地被抛弃了。 现在我想了解这里真正发生的事情。 至于合法性:如果我理解正确地将函数指针强制转换为另一种类型的答案,那么这只是未定义的行为。 因此,运行并产生合理结果的事实只是纯粹的运气,对吗? (或编译器编写者的好看) 为什么gcc不会警告我这个,即使是Wall? 这是编译器无法检测到的东西吗? 为什么? […]

将int转换为指针 – 为什么要先转换为long? (如在p =(void *)42;)

在GLib文档中,有一章关于类型转换宏。 在关于将int转换为*void指针的讨论中,它说(强调我的): 天真的,你可以试试这个,但这是不正确的: gpointer p; int i; p = (void*) 42; i = (int) p; 同样,该示例不正确,请勿复制。 问题是在某些系统上你需要这样做: gpointer p; int i; p = (void*) (long) 42; i = (int) (long) p; (来源:GLib参考手册GLib 2.39.92,章节类型转换宏 )。 为什么long必要? 是否任何需要扩展的int不会自动作为指针转换的一部分发生?

C中的结构和铸造

我在想: 如果我有结构定义,例如,像这样: struct Base { int foo; }; struct Derived { int foo; // int foo is common for both definitions char *bar; }; 我可以这样做吗? void foobar(void *ptr) { ((struct Base *)ptr)->foo = 1; } struct Derived s; foobar(&s); 例如,当其类型实际为Derived *时,将void指针强制转换为Base *来访问它的foo ?

将void指针转换为整数数组

我有一个问题,我有一个指向内存区域的指针。 我想用这个指针来创建一个整数数组。 基本上这就是我所拥有的,指向大小为100 * 300 * 2 = 60000字节的内存地址的指针 unsigned char *ptr = 0x00000000; // fictional point in memory goes up to 0x0000EA60 我想要实现的是将此内存检查为大小为100 * 150 = 15000 ints = 60000字节的整数数组,如下所示: unsigned int array[ 100 ][ 150 ]; 我假设它涉及一些铸造虽然我不确定如何制定它。 任何帮助,将不胜感激。

C / C ++编译器如何处理具有不同值范围的类型之间的类型转换?

如何在不丢失编译器内部数据的情况下进行类型转换? 例如: int i = 10; UINT k = (UINT) k; float fl = 10.123; UINT ufl = (UINT) fl; // data loss here? char *p = “Stackoverflow Rocks”; unsigned char *up = (unsigned char *) p; 编译器如何处理这种类型转换? 显示位的低级示例将受到高度赞赏。

将一个int指针转换为char ptr,反之亦然

问题很简单。 据我了解,GCC认为字符将是字节对齐的,并且在32位环境中对齐4字节对齐。 我也知道C99标准6.3.2.3,它表示在未对齐的指针类型之间进行转换会导致未定义的操作。 C的其他标准对此有何评论? 这里也有许多经验丰富的编码员 – 对此有任何看法将不胜感激。 int *iptr1, *iptr2; char *cptr1, *cptr2; iptr1 = (int *) cptr1; cptr2 = (char *) iptr2;

char和通常的算术转换规则

我知道这个问题已被提出,并且似乎已经回答了无数次,但我似乎无法将答案与我自己的经验相匹配。 C标准规定,对于加法“两个操作数应具有算术类型”(6.5.6.1)。 Arithemitc类型包括整数和浮点类型(6.2.5.18),最后整数类型是char,short,int,long和long long,它们以有符号和无符号类型(6.2.5.4和6.2.5.6)存在。 根据通常算术转换的规则“如果两个操作数具有相同的类型,则不需要进一步转换。” 到现在为止还挺好。 我的理解,如“C书”中所示,“[n] o算术由C以比int短的精度完成”,这是应用积分推广的地方。 我似乎没有在标准中找到这个参考,我好像已经看过很多次了。 由于unsigned char是算术类型,并且通常算术转换的规则表明相同类型的操作数不需要转换,为什么需要进行积分提升? 我使用两个不同的编译器测试了这个。 我写了一个简单的程序,它添加了char: unsigned char a = 1; unsigned char b = 2; unsigned char c = a + b; 目标平台是使用8位架构的Atmel Mega8 uC。 因此,如果操作数应该进行整体提升,则整数加法将需要使用两个寄存器。 使用imagecraft avr编译器进行编译,没有优化,并且启用了严格的ANSI C可移植性选项,产生了这个汇编代码: mov R16, R20 add R16, R18 使用avr-gcc(我不知道类似于gcc的-strict的ANSI开关): $ avr-gcc -O0 -mmcu=atmega8 -S -c main.c 结果汇编: ldd r25,Y+1 ldd […]

“来自指针的整数/整数的指针没有强制转换”问题

这个问题是整数和指针问题之间所有初始化/赋值的FAQ条目。 我想写一个指针设置为特定内存地址的代码,例如0x12345678 。 但是当用gcc编译器编译这个代码时,我得到“初始化使得整数没有强制转换的指针”警告/错误: int* p = 0x12345678; 类似地,这段代码给出了“初始化从没有强制转换的指针生成整数”: int* p = …; int i = p; 如果我在变量声明行之外做同样的事情,那么消息是相同的但是说“赋值”而不是“初始化”: p = 0x12345678; // “assignment makes pointer from integer without a cast” i = p; // “assignment makes integer from pointer without a cast” 其他流行编译器的测试也会给出错误/警告消息: clang说“指针转换不兼容的整数” icc说“ int类型的值不能用于初始化int*类型的实体” MSVC(cl)说“初始化int*与int*的间接级别不同”。 问题:以上示例是否有效? 还有一个后续问题: 这不会给出任何警告/错误: int* p = 0; 为什么不?

如何手动(按位)执行(浮点)x?

现在,这是我应该实现的函数的函数头: /* * float_from_int – Return bit-level equivalent of expression (float) x * Result is returned as unsigned int, but * it is to be interpreted as the bit-level representation of a * single-precision floating point values. * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while * Max ops: 30 * Rating: […]