为啥 memset 在苹果 clang 编译器中工作错误?

Posted

技术标签:

【中文标题】为啥 memset 在苹果 clang 编译器中工作错误?【英文标题】:Why memset works wrong in apple clang compiler?为什么 memset 在苹果 clang 编译器中工作错误? 【发布时间】:2021-08-09 07:33:06 【问题描述】:

我在用 c++ 解决问题时发现了一些奇怪的东西。 使用循环初始化整数数组效果很好,但使用 memset 函数初始化它会出错。 下面是示例程序。

#include <cstdio>
#include <limits>
#include <cstring>

using namespace std;

const int SIZE = 10;
const int INF = numeric_limits<int>::max();

int arr1[SIZE];
int arr2[SIZE];

void printArray(int *arr, int n)

    for(int i = 0; i < n; i++)
        printf("%-10d ", arr[i]);


int main()

    // init with loop
    for(int i = 0; i < SIZE; i++)
        arr1[i] = INF;
    printf("\nINIT WITH LOOP\n");
    printArray(arr1, SIZE);

    // init with memset
    memset(arr2, INF, sizeof(arr2));
    printf("\nINIT WITH MEMSET\n");
    printArray(arr2, SIZE);

    return 0;

结果:

INIT WITH LOOP
2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 
INIT WITH MEMSET
-1         -1         -1         -1         -1         -1         -1         -1         -1         -1                                 

???? 我是否误解了如何使用 memset 函数?或者 ????是错误吗? 供您参考,我的编译器版本如下。

kimseokjin@MacBook-Air LovePS % g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: x86_64-apple-darwin20.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

【问题讨论】:

只需在 C++ 中使用std::fill,这些错误就会消失。 memset(arr, 63, sizeof arr) 应该适用于您的情况。 @amirali 你试过了吗? 如果您的问题是“我是在滥用 X 还是一个错误?”,通常是前者(除非是 php 问题)。 @DanielLangr 我用它将整数数组设置为某种无穷大。 【参考方案1】:

memset 将第二个操作数(参数)转换为unsigned char 并将其复制到所有目标字节中。在您的情况下,生成的 unsigned char 是 0xFF,它复制到 int 类型的所有元素中,其值为 -1。

文档链接:https://en.cppreference.com/w/cpp/string/byte/memset。

建议: 不要使用像memset 这样的低级“C”函数,除非您非常确定自己在做什么并且确实需要它。您不需要在循环中设置数组值,我们在 C++ 中有算法,例如 cmets 中建议的std::fill。您可能还想使用std::array 而不是普通的“C”数组。

一个更类似于 C++ 且更具可读性的替代方案:

std::array<int, SIZE> arr2;
std::fill(std::begin(arr2), std::end(arr2), INF);

【讨论】:

以上是关于为啥 memset 在苹果 clang 编译器中工作错误?的主要内容,如果未能解决你的问题,请参考以下文章

mac 使用gcc 为啥编译错误是clang 提示

为啥以下代码使用clang而不是gcc编译

为啥在编译期间不使用 GCC 选项 -Os?

为啥mac不需要包含智能指针? [复制]

为啥 clang 和 gcc 在这个虚拟继承代码上存在分歧?

变量 args SFINAE 默认构造函数在 clang 中工作,但在 Visual Studio 2015 中失败