如果其中一个是long long unsigned int,则另一个被提升为long long unsigned int
但是,如果我在MSVC下执行以下操作:
unsigned int a = <some expression>;
unsigned long long b = a << 32ULL;
Run Code Online (Sandbox Code Playgroud)
第二行生成以下警告:
warning C4293: '<<': shift count negative or too big, undefined behavior
Run Code Online (Sandbox Code Playgroud)
32ULL
是一个64位无符号值,因此根据隐式转换规则,这应该意味着a
转换unsigned long long
为.因此,我将64位值移位32位,显然是一个定义明确的操作.
MSVC是否有漏洞或者我的逻辑存在缺陷?
c++ bit-shift unsigned-long-long-int integer-promotion language-lawyer
以下是现代C中未定义的行为:
union foo
{
int i;
float f;
};
union foo bar;
bar.f = 1.0f;
printf("%08x\n", bar.i);
Run Code Online (Sandbox Code Playgroud)
并打印1.0f的十六进制表示.
但是以下是未定义的行为:
int x;
printf("%08x\n", x);
Run Code Online (Sandbox Code Playgroud)
那这个呢?
union xyzzy
{
char c;
int i;
};
union xyzzy plugh;
Run Code Online (Sandbox Code Playgroud)
这应该是未定义的行为,因为没有plugh
编写成员.
printf("%08x\n", plugh.i);
Run Code Online (Sandbox Code Playgroud)
但是这个呢.这是未定义的行为吗?
plugh.c = 'A';
printf("%08x\n", plugh.i);
Run Code Online (Sandbox Code Playgroud)
现在大多数C编译器都有sizeof(char) < sizeof(int)
,sizeof(int)
或者是2或4.这意味着在这些情况下,最多plugh.i
会写入50%或25%,但读取剩余的字节将读取未初始化的数据,因此应该是未定义的行为.在此基础上,是整个读取未定义的行为?
演示此问题的代码示例:
#include <functional>
#include <set>
void useCallback(std::function<void(char *)> callback)
{
}
int main()
{
std::function<void(char const *)> callback = [](char const *)
{
};
useCallback(callback);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是的,在const
一天结束时删除是良性的,useCallback()
在其API中声明它准备接受并使用修改其参数的回调,因此它可以很好地使用没有的函数.
那么为什么阻止传递std::set<char *>
给期望std::set<char const *>
不适用的函数的参数呢?该参数正确指出char *
并且char const *
是不同的类型,因此这两个集不是类型等价的.
牢记这一点,为什么不考虑不同的类型callback
和参数useCallback()
?
- 编辑 -
这是使用MSVC,VS 2017.
根据this SO question,Linux executable can't find shared library in same folder传递-Wl,-rpath,${ORIGIN}
是让Linux可执行文件.so
在与可执行文件相同的目录中搜索s的方法。
我们正在使用 cmake,所以我添加了一行表单
target_link_options(Executable PRIVATE -Wl,-rpath=${ORIGIN})
Run Code Online (Sandbox Code Playgroud)
到 CMakeLists.txt。问题在于 cmake 试图将九个字符序列解释${ORIGIN}
为一个变量,并用空替换它。
到目前为止,我已经尝试过:
$${ORIGIN}
\${ORIGIN}
$\{ORIGIN\}
$$\{ORIGIN\}
\$\{ORIGIN\}
Run Code Online (Sandbox Code Playgroud)
这些都没有奏效。我怎样才能做到这一点?
- 编辑 -
正如@Tsyvarev 的评论所指出的,在我的特定情况下,这是一个 XY 问题,因为 cmake 具有直接设计用于操纵 rpath 的设施。使用这个,我能够得到一个解决方案。
就我而言,将以下三行添加到 CMakeLists.txt 就可以了。
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH "$\{ORIGIN\}")
Run Code Online (Sandbox Code Playgroud)
请注意,我们构建过程的一部分涉及将 复制.so
到输出文件夹以准备构建最终的 tarball 工件。因此,使用-rpath=${ORIGIN}
既适用于构建树中的测试,也适用于 Docker 容器中可执行文件的最终安装。
我看了一下Stackoverflow认为可能已经有答案的问题所提出的各种选项,但我看到的并没有结束.
示例代码:
#include <math.h>
class v2
{
public:
float x;
float y;
v2(float angle) : x(cos(angle)), y(sin(angle)) {}
v2(const v2 &v) : x(v.x), y(v.y) {}
};
int main(int argc, char **argv)
{
float const angle(1.0f);
v2 const test1(angle);
v2 const test2(v2(angle));
v2 const test3(test1);
float const x1(test1.x);
float const y1(test1.y);
float const x2(test2.x); // These two lines fail, claiming left of .x must have class type.
float const y2(test2.y);
float const x3(test3.x);
float const y3(test3.y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是来自VS 2010的MSVC.test2的创建正确编译,但其成员的访问失败,声称test2没有类类型. …
众所周知,没有进入 C++20 格式库的一件事是打印到标准输出或通用文件流的函数。我们已承诺std::print()
在 C++23 中满足这一需求,但这并不能解决临时问题。
有什么选择可以解决这个问题?
我正在编写一个自定义客户端和服务器,我想通过公共 Internet 安全地进行通信,因此我想使用 OpenSSL 并让两端都进行对等验证以确保我的客户端不会被 MITM 误导,同样未经授权的客户端无法连接到服务器。
这是在 SSL_connect / SSL_accept 阶段从服务器收到的错误:
15620:error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:ssl\record\rec_layer_s3.c:1528:SSL alert number 48
Run Code Online (Sandbox Code Playgroud)
我在 Windows 10 下运行,使用 OpenSSL 1.1.1。我正在使用以下批处理文件来创建它们。出于显而易见的原因,我手动输入了 ca 私钥密码。
openssl genrsa -out -des3 ca.key.pem 2048
openssl genrsa -out server.key.pem 2048
openssl genrsa -out client.key.pem 2048
openssl req -x509 -new -nodes -key ca.key.pem -sha256 -days 365 -out ca.cert.pem -subj /C=US/ST=CA/L=Somewhere/O=Someone/CN=Foobar
openssl req -new -sha256 -key server.key.pem -subj /C=US/ST=CA/L=Somewhere/O=Someone/CN=Foobar -out server.csr
openssl x509 -req -in server.csr -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -out server.cert.pem …
Run Code Online (Sandbox Code Playgroud) 作为C的初学者,我仍然对魔法"指针"的概念感到困惑
例如,它是一个简单的代码,在数组"range1"中存储一到十个
int *range1;
int max = 10;
int count = 0;
range1 = malloc(sizeof(int) * (11));
while (count < max)
{
range1[count] = count;
count++;
}
range1[count] = '\0';
Run Code Online (Sandbox Code Playgroud)
这很有效,但是
int *range1;
int max = 10;
int count = 0;
range1 = malloc(sizeof(int) * (11));
while (count < max)
{
*range1 = count;
count++;
range1++;
}
range1[count] = '\0';
Run Code Online (Sandbox Code Playgroud)
这个不是.我明白了
[1] 24934 segmentation fault
Run Code Online (Sandbox Code Playgroud)
我很困惑因为我认为*(range1 + count)= range1 [count].
如何更改第二个示例,使其运行而不会产生分段违例.
对于C数组,通常情况下,简单地命名数组与编写&foo[0]
将近50年的东西具有相同的效果。
在我正在处理的项目中,从C样式数组转换为std :: array <>时,出现的绝大多数“错误”是由于C数组的上述属性所致。
在所有情况下,解决方案都很简单,只需追加即可.data()
。但是,我想到精心设计operator T*
应该可以直接解决这个问题。
有任何技术原因无法创建此运算符?