小编Myr*_*ria的帖子

SSE2是否签名整数溢出未定义?

在C和C++中未定义有符号整数溢出.但是在单个字段中有符号整数溢出__m128i呢?换句话说,这种行为是否在英特尔标准中定义?

#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <emmintrin.h>

union SSE2
{
    __m128i m_vector;
    uint32_t m_dwords[sizeof(__m128i) / sizeof(uint32_t)];
};

int main()
{
    union SSE2 reg = {_mm_set_epi32(INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX)};
    reg.m_vector = _mm_add_epi32(reg.m_vector, _mm_set_epi32(1, 1, 1, 1));

    printf("%08" PRIX32 "\n", (uint32_t) reg.m_dwords[0]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
[myria@polaris tests]$ gcc -m64 -msse2 -std=c11 -O3 sse2defined.c -o sse2defined
[myria@polaris tests]$ ./sse2defined
80000000
Run Code Online (Sandbox Code Playgroud)

请注意,SSE2的4字节大小的字段__m128i被视为已签名.

c undefined-behavior sse2 language-lawyer

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

我如何告诉GCC asm输入寄存器被破坏?

我正在尝试通过x86 mul指令执行64 = 32x32乘法,但是我只需要结果的高双字(edx寄存器)。因此,很自然地,我尝试将清单edx作为输出寄存器和eax破坏寄存器。

这对我来说似乎很自然,但eax也是一个输入寄存器。当我尝试告诉GCC eax被破坏时,它会给出错误消息。

__asm__("mull\t%2" : "=d"(div10) : "%a"(UINT32_C(0x1999999A)), "r"(number)
    : "cc", "rax");
Run Code Online (Sandbox Code Playgroud)

如果我尝试这样做,则会引发此错误消息:

divmod10.cpp:76:91: error: can’t find a register in class ‘AREG’ while reloading
‘asm’
divmod10.cpp:76:91: error: ‘asm’ operand has impossible constraints
Run Code Online (Sandbox Code Playgroud)

省略它可以编译,但是会破坏代码。GCC最终依赖于eax不被破坏,这是不正确的:

        movl    $429496730, %eax
#APP
# 76 "divmod10.cpp" 1
        mull    %esi
# 0 "" 2
#NO_APP
        movl    %edx, %esi
#APP
# 78 "divmod10.cpp" 1
        mull    %edx
# 0 "" 2
#NO_APP …
Run Code Online (Sandbox Code Playgroud)

c x86 gcc inline-assembly

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

函数调用的"this"是否以相对于参数的未指定顺序进行?

众所周知(尽管不够广泛>.<)C和C++没有指定评估函数参数的顺序.也就是说,puts()下面的两个s可以以任意顺序出现,作为任意编译器选择:

#include <cstdio>

int Function1() {
    std::puts("Function1");
    return 1;
}

int Function2() {
    std::puts("Function2");
    return 2;
}

int Add(int x, int y) {
    return x + y;
}

int main() {
    return Add(Function1(), Function2());
}
Run Code Online (Sandbox Code Playgroud)

然而,这是否也适用于评价this的左侧.,.*,->还是->*运营商?换句话说,puts()下面的顺序是否未指定?

#include <cstdio>

struct Struct {
    Struct() { std::puts("Struct::Struct"); }
    int Member(int x) const { return x * 2; }
};

int Function() {
    std::puts("Function");
    return 14;
}

int …
Run Code Online (Sandbox Code Playgroud)

c++ this parameter-passing

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

Mac OS是否可以创建匿名文件映射?

在UNIX世界中,创建由RAM或页面文件而不是磁盘文件支持的文件映射对象的标准方法是调用shm_open。这将创建一个具有名称的内存映射,并返回可传递给的文件句柄mmap

问题在于它创建了一个名称。如果我可以创建一个匿名内存映射,那就太好了。这将解决两个问题:

  1. 这样可以避免出现以下问题:同一程序的两个实例可能会占用彼此的映射文件。
  2. 如果程序崩溃或突然终止,它将不会留下共享内存对象。在此shm_unlink之后立即调用shm_open是一种可能,但是这会留下一个小窗口,在该窗口中突然终止会将该对象保留到下次重新启动为止。

在Linux中,有memfd_create解决此问题的方法。同样,Windows允许传递一个空名称CreateFileMappingW来创建匿名映射。

Mac OS是否具有等效功能?

macos shared-memory memory-mapped-files

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

Visual Studio 2017 在构建 Android 本机应用程序时找不到 clang.exe

我在 Visual Studio 2017 15.6.2 中创建了一个全新的 Android 原生项目,并且没有更改单个项目设置或源代码行,点击构建。它失败并出现以下错误:

1>------ Build started: Project: AndroidNDKTest.NativeActivity, Configuration: Debug x86 ------
1>ANDROID_HOME=C:\Program Files (x86)\Android\android-sdk
1>ANT_HOME=
1>JAVA_HOME=C:\Program Files\Java\jdk1.8.0_161
1>NDK_ROOT=C:\ProgramData\Microsoft\AndroidNDK64\android-ndk-r13b
1>pch.h
1>TRACKER : error TRK0005: Failed to locate: "clang.exe". The system cannot find the file specified.
Run Code Online (Sandbox Code Playgroud)

不知道为什么找不到clang.exe,因为它存在:

C:\>dir /s C:\ProgramData\Microsoft\AndroidNDK64\android-ndk-r13b\clang.exe
 Volume in drive C is OSDisk
 Volume Serial Number is 1234-ABCD

 Directory of C:\ProgramData\Microsoft\AndroidNDK64\android-ndk-r13b\toolchains\llvm\prebuilt\windows-x86_64\bin

03/08/2017  03:24 PM        43,847,680 clang.exe
Run Code Online (Sandbox Code Playgroud)

android clang visual-studio

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

在 ARM64 汇编代码中,什么时候寄存器 31 XZR 与 SP?

在ARM64汇编代码中,寄存器号31什么时候表示XZR,什么时候表示SP?

assembly machine-code cpu-registers instructions arm64

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

是否存在用于C中的add-with-carry的ARM内在函数?

是否存在ARM C编译器的内在函数来执行随身携带操作,或者是否需要使用汇编语言?

在x86上,有_addcarry_u64for-carry-carry.(_addcarryx_u64特殊目的还有更新的.)

arm intrinsics

4
推荐指数
1
解决办法
443
查看次数

static_assert是否合法,签名右移有两个补码行为?

在C11,C++ 11和C++ 14中执行以下操作是否合法?

static_assert(((-4) >> 1) == -2, "my code assumes sign-extending right shift");
Run Code Online (Sandbox Code Playgroud)

或等效的C:

_Static_assert(((-4) >> 1) == -2, "my code assumes sign-extending right shift");
Run Code Online (Sandbox Code Playgroud)

我不知道关于是否可以使用如上所述的实现定义的操作的常量表达式的规则.

我知道,无论机器类型如何,相反的,带负数的左移符号都是未定义的.

c c++ language-lawyer c++11 c11

3
推荐指数
1
解决办法
235
查看次数

在 Linux 中实现快速的“GetCurrentThreadId”

Windows NT 有一个很好的函数GetCurrentThreadId,它的名字暗示了它的作用。它的实现非常快,因为它只是从线程本地存储中读取一个变量,该变量在 NT 内核创建线程期间写入那里。我想在 Linux 中实现它,但我遇到了一个障碍。

我最初的实现是这样的:

typedef pid_t ThreadID;

ThreadID GetCurrentThreadId(void)
{
    static __thread ThreadID t_cachedID = (ThreadID) -1;

    if (__builtin_expect(t_cachedID == (ThreadID) -1, 0))
    {
        t_cachedID = (ThreadID) syscall(__NR_gettid);
    }

    return t_cachedID;
}
Run Code Online (Sandbox Code Playgroud)

问题是fork。在程序,使用forkt_cachedID变得陈旧-新的子进程的主线程有线程的线程本地存储的副本叫fork,那t_cachedID就是不再正确。

解决方案应该是pthread_atfork,以便t_cachedID将新子进程中的值更改为 -1,但作为 Pthreads API 的规范,它的设计很差。如果你是被使用卸载一个DLL dlclosepthread_atfork不知道这一点,仍然会尽力呼吁一个你的函数fork,并KABOOM。糟糕的设计决策#1。也没有 API 可以删除您的回调函数。糟糕的设计决策#2。

有一个模糊记录的 glibc 函数__register_atfork似乎旨在处理这个问题,但它需要一个 DLL 句柄,而不是提供一种删除*_atfork处理程序的方法。glibc 在尝试解决 POSIX 糟糕的设计决策时做出的糟糕的设计决策 #1。

如何获得我自己的 …

linux multithreading posix pthreads

2
推荐指数
1
解决办法
3632
查看次数

ARM64 是否有故意未定义的操作码?

我想触发一个有意的未定义操作码异常。ARM64 是否有像 x86ud2和 ARM32一样显式保留为未定义的指令udf

opcode arm64

2
推荐指数
1
解决办法
65
查看次数

realloc()悬空指针和未定义的行为

当你释放内存时,指向内存的指针会发生什么?他们立即变得无效吗?如果他们以后再次有效会怎么样?

当然,指针变为无效然后再次变为"有效"的通常情况是将其他对象分配到之前使用的内存,如果使用指针访问内存,那么这显然是未定义的行为.悬空指针内存覆盖了第1课,差不多.

但是如果内存再次对同一个分配有效呢?只有一种标准方式可以实现:realloc().如果你有一个指向malloc()偏移量'd存储块内某处的指针> 1,那么使用realloc()缩小块到小于你的偏移量,显然你的指针变得无效.如果你再次使用realloc()增长块至少覆盖悬空指针指向的对象类型,并且在任何情况下都没有realloc()移动内存块,悬空指针是否再次有效?

这是一个极端的案例,我真的不知道如何解释C或C++标准来解决它.以下是显示它的程序.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    static const char s_message[] = "hello there";
    static const char s_kitty[] = "kitty";

    char *string = malloc(sizeof(s_message));
    if (!string)
    {
        fprintf(stderr, "malloc failed\n");
        return 1;
    }

    memcpy(string, s_message, sizeof(s_message));
    printf("%p %s\n", string, string);

    char *overwrite = string + 6;
    *overwrite = '\0';
    printf("%p %s\n", string, string);

    string[4] = '\0';
    char *new_string = …
Run Code Online (Sandbox Code Playgroud)

c pointers realloc undefined-behavior dangling-pointer

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

为什么NULL不能成为函数指针模板参数?

当我尝试在GCC或clang中编译它时,我收到一个错误.

#include <cstddef>

template <void (*Function)()>
void Wrapper()
{
}

int main()
{
    void (*meow)() = Wrapper<NULL>;
    return meow ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)
$ g++ -m64 -std=c++11 -c nulltemplate.cpp
nulltemplate.cpp: In function ‘int main()’:
nulltemplate.cpp:10:19: error: no matches converting function ‘Wrapper’ to type ‘void (*)()’
nulltemplate.cpp:4:6: error: candidate is: template<void (* Function)()> void Wrapper()
Run Code Online (Sandbox Code Playgroud)

为什么我不能这样做?错误的措辞就好像Wrapper是一个无法在上下文中解析为特定函数指针类型的重载,这对我来说没有意义.

c++ templates c++11

0
推荐指数
1
解决办法
89
查看次数