我知道sockaddr_in用于IPv4,sockaddr_in6用于IPv6.我的困惑是sockaddr和sockaddr_in之间的区别[6].
有些函数接受sockaddr,有些函数接受sockaddr_in或sockaddr_in6,所以:
而且因为sizeof(sockaddr_in6) > sizeof(sockaddr) == sizeof(sockaddr_in).
一个例子是:我们有一个套接字,我们想得到它的字符串IP地址(它可以是ipv4或ipv6).
我们首先打电话getsockname来获得一个addr然后inet_ntop基于的电话addr.sa_family.
这段代码片段有什么问题吗?
char ipStr[256];
sockaddr_in6 addr_inv6;
sockaddr* addr = (sockaddr*)&addr_inv6;
sockaddr_in* addr_in = (sockaddr_in*)&addr_inv6;
socklen_t len = sizeof(addr_inv6);
getsockname(_socket, addr, &len);
if (addr->sa_family == AF_INET6) {
inet_ntop(addr_inv6.sin6_family, &addr_inv6.sin6_addr, ipStr, sizeof(ipStr));
// <<<<<<<<IS THIS LINE VALID, getsockname expected a sockaddr, but we use
// it output parameter as sockaddr_in6.
} else {
inet_ntop(addr_in->sin_family, &addr_in->sin_addr, …Run Code Online (Sandbox Code Playgroud) 我刚检查了C++标准.看来以下代码不应该是未定义的行为:
unsigned int val = 0x0FFFFFFF;
unsigned int res = val >> 34; // res should be 0 by C++ standard,
// but GCC gives warning and res is 67108863
Run Code Online (Sandbox Code Playgroud)
并从标准:
E1 >> E2的值是E1右移E2位位置.如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1/2 ^ E2的商的整数部分.如果E1具有有符号类型和负值,则生成的值是实现定义的.
根据标准,由于34不是负数,因此变量res将为0.
GCC为代码段提供以下警告,并且res是67108863:
警告:右移计数> =类型的宽度
我还检查了GCC发出的汇编代码.它只是调用SHRL,而SHRL的英特尔指令文件res不是ZERO.
那么这是否意味着GCC没有在英特尔平台上实现标准行为?
我正在研究用于Windows平台的遗留代码.当我编译代码时VS2013,它会发出以下警告:
错误C4996:'
fopen':此函数或变量可能不安全.考虑fopen_s改用.要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS.详情请参见在线帮助."
它也会给出一个熟悉的警告sprintf.sprintf_s由于缓冲区溢出,我理解比sprintf更安全.
但是如何使fopen_s更安全fopen,因为fopen不接受缓冲区就没有缓冲区溢出的可能性.任何人都可以提供一个fopen不安全的案件,fopen_s是否安全?
我将在utilA.cpp中有以下代码片段:
// utilB.h
namespace xm
{
void zoo(struct tm timeval); //<-----line 0
}
// utilA.cpp
#include <utilB.h> //<----line 1
#include <time.h> //<----line 2
namespace xm
{
void foo()
{
struct tm time1 = {0}; //<----line 3
}
}
Run Code Online (Sandbox Code Playgroud)
GCC在编译utilA.cpp时抱怨,
error: variable 'xm::tm time1' has initializer but incomplete type
Run Code Online (Sandbox Code Playgroud)
这似乎是因为它在第0行utilA.h使用struct tm,但没有包括time.h,并且编译器将第struct tm0行视为前向声明,因此第struct tm2 xm::tm行在第0行的头部内被解析.
那么C++标准是否将此struct tm函数参数定义为前向声明?请帮助解释一下,标准中的引用会有所帮助.
我正在解析网络数据流,我想知道是否有任何方法可以将数据流直接映射到数据结构.
例如,我想如下定义RTP协议的数据结构.
class RTPHeader
{
int version:2; // The first two bits is version.
int P:1; // The next bits is an field P.
int X:1;
int CC:4;
int M:1;
int PT:7;
int sequenceNumber;
int64 timestamp;
.....
};
Run Code Online (Sandbox Code Playgroud)
并以这种方式使用它.
RTPHeader header;
memcpy(&header, steamData, sizeof(header));
Run Code Online (Sandbox Code Playgroud)
但是,由于C++编译器将在成员之间插入填充,有没有办法控制它,以便在成员之间不添加填充(包括位字段成员)?
这个问题不是如何摆脱结构的数据成员之间的填充字节,因为在我的例子中可能有位字段.
我刚刚意识到SignalObjectAndWaitWindows平台有API功能.但是,已经有SetEvent和WaitForSingleObject.您可以一起使用它们来实现相同的目标SignalObjectAndWait.
基于MSDN,SignalObjectAndWait比单独调用SetEvent和更有效WaitForSingleObject.它还指出:
线程可以使用该
SignalObjectAndWait函数来确保工作线程在发信号通知对象之前处于等待状态.
我不完全理解这句话,但似乎效率并不是我们需要的唯一原因SignalObjectAndWait.任何人都可以提供SetEvent+ WaitForSingleObject无法提供提供的功能的场景SignalObjectAndWait吗?
据我所知,memmove和memcpy不同的是,memmove处理内存重叠的情况.我已经检查了libgcc中的实现,并从intel网站获得了这篇文章[memcpy performance].
在libgcc中,memmove类似于memcpy,只是通过一个字节和一个字节,因此即使在优化之后性能应该几乎相同.
有人测量了这个并得到了这篇文章记忆,memmove和Speed over Safety.即使我不认为它memmove可以比速度更快memcpy,但至少在Intel平台上应该没有大的差别.
因此,在什么平台和如何,memcpy可以明显更快memmove,如果没有,为什么提供两个类似的功能,而不仅仅是memmove,并导致很多错误.
编辑:我不是要求memmove和memcpy的区别,我知道memmove可以处理重叠问题.问题是有没有memcpy比memmove更快的平台?
我们是在两个工作C++的代码基础,让我们把它叫做一个和乙的一个是构建作为一个库,并分发头文件.h和.a文件到乙.
假设A中有Lock.h文件如下:
// Lock.h in code base A
class Lock {
... ...
#ifdef TRACK_THREAD_OWNER_FOR_DEBUG
virtual int GetLockOwner();
#endif
... ...
private:
CriticalSection section;
#ifdef TRACK_THREAD_OWNER_FOR_DEBUG
int threadOwner;
#endif
};
// Caller.cc in code base B
#include "xxx/xxx/Lock.h"
Lock lockObject;
lockObject.Lock();
Run Code Online (Sandbox Code Playgroud)
在代码库A中,我们默认启用TRACK_THREAD_OWNER_FOR_DEBUG并可能在最终发布日之前更改它.
我们遇到了一些难题,因为A和BTRACK_THREAD_OWNER_FOR_DEBUG不同,导致内存损坏,因为两个库不同.sizeof(Lock)
那么如何防止这个错误呢?caller.cc如果构建宏TRACK_THREAD_OWNER_FOR_DEBUG在两个项目中不同,我们可以在构建文件时触发编译器错误吗?
我目前从我们的 configure.ac 构建脚本中读取了这一行。我在谷歌上搜索过答案,但没有找到。
我认为它是 shell 脚本,但这意味着什么,尤其是对于--?
set -- "$progname" "$@"
Run Code Online (Sandbox Code Playgroud) 只知道我们是否使用默认调用pthread_create pthread_attr_t,然后Posix将保留其他线程的退出线程信息来查询它,如果我们没有调用则会出现僵尸线程泄漏pthread_join.
但据我所知,在Windows平台上,您不需要调用WaitForSingleObject或GetExitCodeThread在线程存在之后.
那么如何Win32处理僵尸线程问题,会有资源泄漏吗?