在过去的一年里,我使用以下代码从 Xilinx ARM Linux 中的地址空间中读取数据,并且它已经工作了(如,编译时没有错误并产生了预期的结果):
void *ctl_ptr = mmap(NULL,Length , PROT_READ|PROT_WRITE, MAP_SHARED, fd, ctl_addr);
// Read Status
int status = *((unsigned *)(ctl_ptr + C_FIFO_ISR));
// Clear Interrupts
*((unsigned *)(ctl_ptr + C_FIFO_ISR)) = 0xffffff;
一位同事今天提到,这段代码甚至不应该工作,因为它是空指针算术。现在我很困惑到底为什么它一直有效?
这是一个 void 指针算术的示例(看起来确实如此),如果是,为什么它有效?
更多信息:
我一直在使用 Xilinx SDK 2014.1,这是包含上述内容的文件的编译结果:
19:09:55 **** Auto Build of configuration Debug for project ZynqPSPLTest ****
make all
Building file: ../src/ZynqPSPLTest.c
Invoking: ARM Linux gcc compiler
arm-xilinx-linux-gnueabi-gcc -Wall -O0 -g3 -c -fmessage-length=0 -MMD -MP -MF"src/ZynqPSPLTest.d" -MT"src/ZynqPSPLTest.d" -o "src/ZynqPSPLTest.o" "../src/ZynqPSPLTest.c"
Finished building: ../src/ZynqPSPLTest.c
Building target: ZynqPSPLTest.elf
Invoking: ARM Linux gcc linker
arm-xilinx-linux-gnueabi-gcc -o "ZynqPSPLTest.elf" ./src/ZynqPSPLTest.o
Finished building target: ZynqPSPLTest.elf
make --no-print-directory post-build
Copy Elf to share
cp /media/work/stacey/zynq_eval/EvalDebug/sdk/ZynqPSPLTest/Debug/ZynqPSPLTest.elf /home/stacey/build_share
Invoking: ARM Linux Print Size
arm-xilinx-linux-gnueabi-size ZynqPSPLTest.elf |tee "ZynqPSPLTest.elf.size"
text data bss dec hex filename
11339 328 4 11671 2d97 ZynqPSPLTest.elf
Finished building: ZynqPSPLTest.elf.size
19:09:56 Build Finished (took 720ms)
这是版本输出:
[stacey@centos6 bin]$ ./arm-xilinx-linux-gnueabi-gcc -v
Using built-in specs.
COLLECT_GCC=./arm-xilinx-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/media/work/Xilinx/SDK/2014.1/gnu/arm/lin/bin/../libexec/gcc/arm-xilinx-linux-gnueabi/4.8.1/lto-wrapper
Target: arm-xilinx-linux-gnueabi
Configured with: /scratch/janisjo/build7/2013.11-xilinx-linux-respin1/src/gcc-4.8-2013.11/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-xilinx-linux-gnueabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-arch=armv5te --with-arch=armv7-a --with-cpu=cortex-a9 --with-float=softfp --with-fpu=neon-fp16 --disable-multilib --with-gnu-as --with-gnu-ld --with-specs='%{save-temps: -fverbose-asm} %{funwind-tables|fno-unwind-tables|mabi=*|ffreestanding|nostdlib:;:-funwind-tables} -D__CS_SOURCERYGXX_MAJ__=2013 -D__CS_SOURCERYGXX_MIN__=11 -D__CS_SOURCERYGXX_REV__=53' --enable-languages=c,c++ --enable-shared --enable-lto --enable-symvers=gnu --enable-__cxa_atexit --with-pkgversion='Sourcery CodeBench Lite 2013.11-53' --with-bugurl=https://sourcery.mentor.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-sysroot=/opt/codesourcery/arm-xilinx-linux-gnueabi/libc --with-build-sysroot=/scratch/janisjo/build7/2013.11-xilinx-linux-respin1/install/opt/codesourcery/arm-xilinx-linux-gnueabi/libc --with-gmp=/scratch/janisjo/build7/2013.11-xilinx-linux-respin1/obj/pkg-2013.11-53-arm-xilinx-linux-gnueabi/xilinx-2013.11-53-arm-xilinx-linux-gnueabi.extras/host-libs-i686-pc-linux-gnu/usr --with-mpfr=/scratch/janisjo/build7/2013.11-xilinx-linux-respin1/obj/pkg-2013.11-53-arm-xilinx-linux-gnueabi/xilinx-2013.11-53-arm-xilinx-linux-gnueabi.extras/host-libs-i686-pc-linux-gnu/usr --with-mpc=/scratch/janisjo/build7/2013.11-xilinx-linux-respin1/obj/pkg-2013.11-53-arm-xilinx-linux-gnueabi/xilinx-2013.11-53-arm-xilinx-linux-gnueabi.extras/host-libs-i686-pc-linux-gnu/usr --with-isl=/scratch/janisjo/build7/2013.11-xilinx-linux-respin1/obj/pkg-2013.11-53-arm-xilinx-linux-gnueabi/xilinx-2013.11-53-arm-xilinx-linux-gnueabi.extras/host-libs-i686-pc-linux-gnu/usr --with-cloog=/scratch/janisjo/build7/2013.11-xilinx-linux-respin1/obj/pkg-2013.11-53-arm-xilinx-linux-gnueabi/xilinx-2013.11-53-arm-xilinx-linux-gnueabi.extras/host-libs-i686-pc-linux-gnu/usr --disable-libgomp --disable-libitm --disable-libssp --enable-poison-system-directories --with-build-time-tools=/scratch/janisjo/build7/2013.11-xilinx-linux-respin1/install/opt/codesourcery/arm-xilinx-linux-gnueabi/bin --with-build-time-tools=/scratch/janisjo/build7/2013.11-xilinx-linux-respin1/install/opt/codesourcery/arm-xilinx-linux-gnueabi/bin SED=sed
Thread model: posix
gcc version 4.8.1 (Sourcery CodeBench Lite 2013.11-53)
最佳答案
gcc
有 extension允许 void 指针算术,请参阅 the documentation: Arithmetic on void- and Function-Pointers :
In GNU C, addition and subtraction operations are supported on pointers to void and on pointers to functions. This is done by treating the size of a void or of a function as 1.
A consequence of this is that sizeof is also allowed on void and on function types, and returns 1.
The option -Wpointer-arith requests a warning if these extensions are used.
关于c - Xilinx ARM 编译器不会提示 void 指针算术,并且会生成正确的结果。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31299482/