我正在阅读C中的库,但我还没有找到对象文件的解释.任何其他编译文件和目标文件之间的真正区别是什么?
如果有人能用人类语言解释,我会很高兴.
如果将负浮点值转换为无符号整数类型的值,会发生什么?标准报价将不胜感激.我面临的问题是从变量类转换为无符号整数类型的值,它包含一个浮点类型的对象.
例:
unsigned i = -.1;
Run Code Online (Sandbox Code Playgroud) 这不是解决特定问题的典型问题,而是大脑练习,但我想知道是否有人有解决方案.
在开发中,我们经常需要禁用或切换代码的某些部分以检查不同的方法.要做到这一点,我们使用评论或#defines
,但我最喜欢的是:
//*
[code here]
//*/
Run Code Online (Sandbox Code Playgroud)
现在当你只删除第一个斜杠时,代码将被注释掉.
问题:有没有办法实现类似的if-else代码切换?我试图找到它,但我总是有一些问题,无法找到一个有效的解决方案.
也许你知道任何类似的技巧吗?
在C或C++中,当运算符在运算符中时,不执行递增和递减运算符(++n
,--n
)sizeof()
.
int n = 100;
int size_int = sizeof(++n);
std::cout<<n;
Run Code Online (Sandbox Code Playgroud)
我编写了这段代码并运行程序.当然,我认为101将会为我展示.但是,n
不是101,它是100.
这是为什么?
#include <stdio.h>
int main()
{
const int a = 12;
int *p;
p = &a;
*p = 70;
}
Run Code Online (Sandbox Code Playgroud)
它会起作用吗?
我已经在Windows 7 32位机器上成功安装了MinGW,并尝试使用命令行或MinGW控制台编译一个简单的程序.
代码在printf语句中有故意错误:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
printf("%d\n" , 3.14 ) ;
return 0 ;
}
Run Code Online (Sandbox Code Playgroud)
该命令gcc -Wall hello.c
给出了正确的警告:hello.c:7:2:警告:格式'%d'需要类型'int'的参数...
但该命令gcc -std=c99 -Wall hello.c
没有给出任何警告.
两者都创建一个可执行文件a.exe(运行并给出相同的结果).
(有趣的是,命令gcc -std=gnu99 -Wall hello.c
会发出警告.)
我不知道这是一个错误,还是安装出错了,但两者似乎都不太可能,因为编译器工作并成功编译了一个更大的项目(但当使用-std = c99时,同样的警告当然会被忽略).
我一定错过了一些信息.
(ps:如果有人安装了新的MinGW,请测试一下.)
gcc版本4.8.1(GCC)
更新1:
_GNU_SOURCE
在包含之前定义stdio.h
即使使用也会删除警告 gcc -Wall hello.c
.
更新2(可能不太相关):
编译
printf("%lf\n" , 3.14 ) ;
Run Code Online (Sandbox Code Playgroud)
-std=c99
标志输出:0.000000
-std=gnu99
输出:3.140000
并编译:
printf("%f\n" , 3.14 ) ;
Run Code Online (Sandbox Code Playgroud)
-std=gnu99
和-std=c99
输出:3.140000
更新3: …
(通过部分初始化,我的意思是定义为未初始化,其中一个成员设置为某个有效值,但不是全部.并且本地我的意思是使用自动存储持续时间定义.这个问题只讨论那些.)
使用可以使用register定义的自动未初始化变量,因为rvalue是未定义的行为.可以使用寄存器存储类说明符定义结构.
6.3.2.1
- 如果左值指定了一个自动存储持续时间的对象,该对象可以使用寄存器存储类声明(从未使用其地址),并且该对象未初始化(未使用初始化程序声明,并且在使用之前未对其进行任何赋值) ),行为未定义.
请注意,它具体说明并且没有对其进行任何分配.
另外我们知道结构不能是陷阱值:
6.2.6.1.
- 结构或联合对象的值永远不是陷阱表示,即使结构或联合对象的成员的值可能是陷阱表示
因此,返回未初始化的结构显然是未定义的行为.
声明:定义了返回一个未初始化的结构,该结构的一个成员被赋予了有效值.
更容易理解的示例:
struct test
{
int a;
int b;
};
struct test Get( void )
{
struct test g;
g.a = 123;
return g;
}
{
struct test t = Get();
}
Run Code Online (Sandbox Code Playgroud)
我碰巧专注于回归,但我相信这也适用于简单的任务,没有任何区别.
我的陈述是否正确?
我有一个看起来像这样的宏:
M(id,...)
Run Code Online (Sandbox Code Playgroud)
如果有id == 0
别的话,我希望它扩展到什么都没有.
这可能吗?如果是这样,怎么样?
我的第一直觉是尝试这样的事情:
#define M(id,...) M##id(__VA_ARGS__)
#define M0(...)
#define M_NOT_0(...) some_code(__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
但是这里的最后一行显然是无效的,我无法找到使这种模式有效的方法.
笔记:
id
是一个0到255之间的整数,但理想情况下我想避免创建256个单独的宏定义.M(id,...)
宏本身不能改变.A,B和C是某些无符号整数类型的变量.从概念上讲,A是测试向量,B是"必需"位的位掩码(必须设置A中的至少一个对应位),并且C是"禁止"位的位掩码(可以不设置A中的相应位).因为我们正在混合按位和逻辑运算符,否则看起来很自然的解决方案
A & B & ~C
Run Code Online (Sandbox Code Playgroud)
是不正确的.相反,标题表达式等同于伪代码
((a0 & b0) | ... | (an & bn)) & (~(a0 & c0) & ... & ~(an & cn))
Run Code Online (Sandbox Code Playgroud)
其中a0
,等等表示各个位(并且n
是最高位的索引).我没有看到如何有效地重新排列这个并提取相应的代码但是,有没有一种聪明的方法,也许有^
,简化标题中的表达式?
编辑:提示@ huseyintugrulbuyukisik的问题我注意到我们可以假设(B & C) == 0
,但我不知道这是否有帮助.
编辑2:结果:这取决于分支预测的好坏!
#include <chrono>
#include <cmath>
#include <iostream>
#include <vector>
using UINT = unsigned int;
int main(void)
{
const auto one = UINT(1);
const UINT B = (one << 9); // Version 1
// const UINT B = (one …
Run Code Online (Sandbox Code Playgroud) 是否允许跳转到内部范围或兄弟范围内的标签?如果是这样,是否允许使用在该范围内声明的变量?
考虑以下代码:
int cond(void);
void use(int);
void foo()
{
{
int y = 2;
label:
use(y);
}
{
int z = 3;
use(z);
/* jump to sibling scope: */ if(cond()) goto label;
}
/* jump to inner scope: */ if(cond()) goto label;
}
Run Code Online (Sandbox Code Playgroud)
这些goto
合法吗?
如果是这样,y
当我跳转label
并保持分配给它的最后一个值(2
)时,保证存在?
或者允许编译器假设y
在超出范围后不会被使用,这意味着单个内存位置可以用于y
和z
?
如果此代码的行为未定义,我如何让GCC发出警告?