小编Zij*_*gWu的帖子

sockaddr,sockaddr_in和sockaddr_in6有什么区别?

我知道sockaddr_in用于IPv4,sockaddr_in6用于IPv6.我的困惑是sockaddr和sockaddr_in之间的区别[6].

有些函数接受sockaddr,有些函数接受sockaddr_insockaddr_in6,所以:

  • 规则是什么?
  • 为什么需要两种不同的结构?

而且因为sizeof(sockaddr_in6) > sizeof(sockaddr) == sizeof(sockaddr_in).

  • 这是否意味着如果我们需要支持ipv4和ipv6,我们应该总是使用sockaddr_in6在堆栈中分配内存并转换为sockaddr和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 c++ api network-programming

42
推荐指数
2
解决办法
3万
查看次数

如果计数大于类型的宽度,是右移未定义的行为吗?

我刚检查了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为代码段提供以下警告,并且res67108863:

警告:右移计数> =类型的宽度

我还检查了GCC发出的汇编代码.它只是调用SHRL,而SHRL的英特尔指令文件res不是ZERO.

那么这是否意味着GCC没有在英特尔平台上实现标准行为?

c++ assembly standards gcc undefined-behavior

32
推荐指数
2
解决办法
6393
查看次数

fopen_s如何比fopen更安全?

我正在研究用于Windows平台的遗留代码.当我编译代码时VS2013,它会发出以下警告:

错误C4996:' fopen':此函数或变量可能不安全.考虑fopen_s改用.要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS.详情请参见在线帮助."

它也会给出一个熟悉的警告sprintf.sprintf_s由于缓冲区溢出,我理解比sprintf更安全.

但是如何使fopen_s更安全fopen,因为fopen不接受缓冲区就没有缓冲区溢出的可能性.任何人都可以提供一个fopen不安全的案件,fopen_s是否安全?

c++ windows crt msvcrt tr24731

22
推荐指数
1
解决办法
1万
查看次数

为什么这是C++中的前向声明?

我将在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函数参数定义为前向声明?请帮助解释一下,标准中的引用会有所帮助.

c++ standards forward-declaration language-lawyer

18
推荐指数
2
解决办法
1461
查看次数

有没有办法控制C++中结构成员(包括位字段)之间的填充?

我正在解析网络数据流,我想知道是否有任何方法可以将数据流直接映射到数据结构.

例如,我想如下定义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++编译器将在成员之间插入填充,有没有办法控制它,以便在成员之间不添加填充(包括位字段成员)?

这个问题不是如何摆脱结构的数据成员之间的填充字节,因为在我的例子中可能有位字段.

c c++ padding

12
推荐指数
2
解决办法
2231
查看次数

SignalObjectAndWait关于SetEvent和WaitForSingleObject的目的是什么?

我刚刚意识到SignalObjectAndWaitWindows平台有API功能.但是,已经有SetEventWaitForSingleObject.您可以一起使用它们来实现相同的目标SignalObjectAndWait.

基于MSDN,SignalObjectAndWait比单独调用SetEvent和更有效WaitForSingleObject.它还指出:

线程可以使用该SignalObjectAndWait函数来确保工作线程在发信号通知对象之前处于等待状态.

我不完全理解这句话,但似乎效率并不是我们需要的唯一原因SignalObjectAndWait.任何人都可以提供SetEvent+ WaitForSingleObject无法提供提供的功能的场景SignalObjectAndWait吗?

c++ windows winapi multithreading multiprocessing

6
推荐指数
1
解决办法
2208
查看次数

在什么平台memmove和memcpy可以有显着的性能差异?

据我所知,memmovememcpy不同的是,memmove处理内存重叠的情况.我已经检查了libgcc中的实现,并从intel网站获得了这篇文章[memcpy performance].

在libgcc中,memmove类似于memcpy,只是通过一个字节和一个字节,因此即使在优化之后性能应该几乎相同.

有人测量了这个并得到了这篇文章记忆,memmove和Speed over Safety.即使我不认为它memmove可以比速度更快memcpy,但至少在Intel平台上应该没有大的差别.

因此,在什么平台和如何,memcpy可以明显更快memmove,如果没有,为什么提供两个类似的功能,而不仅仅是memmove,并导致很多错误.

编辑:我不是要求memmove和memcpy的区别,我知道memmove可以处理重叠问题.问题是有没有memcpy比memmove更快的平台?

c c++ performance

6
推荐指数
1
解决办法
1227
查看次数

如何使用相同的宏确保不同的C++代码库?

我们是在两个工作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并可能在最终发布日之前更改它.

我们遇到了一些难题,因为ABTRACK_THREAD_OWNER_FOR_DEBUG不同,导致内存损坏,因为两个库不同.sizeof(Lock)

那么如何防止这个错误呢?caller.cc如果构建宏TRACK_THREAD_OWNER_FOR_DEBUG在两个项目中不同,我们可以在构建文件时触发编译器错误吗?

c++ macros

6
推荐指数
1
解决办法
113
查看次数

shell 脚本中的“set --”$progname”“$@””是什么意思?

我目前从我们的 configure.ac 构建脚本中读取了这一行。我在谷歌上搜索过答案,但没有找到。

我认为它是 shell 脚本,但这意味着什么,尤其是对于--?

set -- "$progname" "$@"
Run Code Online (Sandbox Code Playgroud)

linux shell

5
推荐指数
2
解决办法
5495
查看次数

为什么Win32没有僵尸线程问题?

只知道我们是否使用默认调用pthread_create pthread_attr_t,然后Posix将保留其他线程的退出线程信息来查询它,如果我们没有调用则会出现僵尸线程泄漏pthread_join.

但据我所知,在Windows平台上,您不需要调用WaitForSingleObjectGetExitCodeThread在线程存在之后.

那么如何Win32处理僵尸线程问题,会有资源泄漏吗?

c++ winapi multithreading posix

5
推荐指数
1
解决办法
304
查看次数