【发布时间】:2019-12-18 00:47:50
【问题描述】:
我正在尝试使用https://github.com/gdelugre/literal_ipaddr,它说它是一个
inet_addr/inet_aton/inet_pton 的 C++17 constexpr 实现
当我这样做时:
auto ipSourceAddressTest = IPAddr::inet_pton<AF_INET>("127.0.0.1");
std::cout << "ipSourceAddressTest is " << ipSourceAddressTest.s_addr << std::endl;
这很好用。我得到十进制的 IP 地址。
但是:
std::string ipv4address;
//get ipv4address from world here
const unsigned int ipMaxSize = 200;
char ip[ipMaxSize];
std::copy(ipv4address.begin(), ipv4address.end(), ip);
auto ipSourceAddress = IPAddr::inet_pton<AF_INET>(ip);
std::cout << "ipSourceAddress is " << ipSourceAddress.s_addr << std::endl;
记住ipSourceAddress.s_addr 是uint32_t。我打印的值不是十进制的 IP,而是4294967295,即二进制的111...111。所以我认为它在编译时而不是运行时获得了它的价值。
如果我这样做了
constexpr auto in_addr1 = IPAddr::inet_pton<AF_INET>(ip);
那么它的值将在编译时推导出来是可以理解的。但是我没有在我的变量声明中使用constexpr。 auto 是否暗示constexpr?
根据https://en.cppreference.com/w/cpp/language/constexpr,
在函数或静态成员变量中使用的 constexpr 说明符 (C++17 起) 声明意味着内联
那么为什么函数inet_pton 会在编译时获得它的价值?
【问题讨论】:
-
你怎么知道它是在编译时计算的?你看过生成的程序集吗?注意:您的
ip数组未初始化(因为ipv4address为空,因此std::copy什么也不做),因此使用它是未定义的行为。 -
可以在运行时调用
constexpr函数。如果可能,它只会在编译时计算。 -
@AlgirdasPreidžius ipv4address 不是空的,在评论中我是从世界上得到的。
-
@GuerlandoOCs "ipv4address 不是空的,在评论中我是从世界上得到的。" 然后,请提供minimal reproducible example。更多信息:
ip在IPAddr::inet_pton<AF_INET>(ip);中是否被视为以空字符结尾的字符串(C 字符串)?如果是这样,这是未定义的行为,即使ipv4address不为空,因为std::copy不会复制空终止符。 -
@KaenbyouRin 查看该库,它似乎主要用于编译时使用,并且仅接受
char数组,而不接受指针。