我在下面的代码中遇到了问题,我想了解为什么它不起作用。当我直接使用从函数返回的结构体中的字符串时,我得到一种奇怪的行为。
第一个printf没问题,与第二个和第三个相同,但是由于某种原因,最后一个出现分段错误或仅打印随机字符串。如果我尝试在结构而不是数组中使用char指针,则不会出现问题。
#include <stdio.h>
typedef struct
{
int value;
char string[23];
} Test;
Test func()
{
Test nuovo = {5, "test"};
return nuovo;
}
int main()
{
Test test = func();
printf("\n1: %d", func().value);
printf("\n2: %s", test.string);
printf("\n3: %s", &(func().string[0]));
printf("\n0: %s", func().string);
return 0;
}
输出:
====================[ Build | test | Debug ]====================================
"C:\Program Files\JetBrains\CLion 2018.2.6\bin\cmake\win\bin\cmake.exe" --build C:\Users\rober\CLionProjects\test\cmake-build-debug --target test -- -j 4
"C:\Program Files\JetBrains\CLion 2018.2.6\bin\cmake\win\bin\cmake.exe" -SC:\Users\rober\CLionProjects\test -BC:\Users\rober\CLionProjects\test\cmake-build-debug --check-build-system CMakeFiles\Makefile.cmake 0
C:/MinGW/bin/mingw32-make.exe -f CMakeFiles\Makefile2 test
mingw32-make.exe[1]: Entering directory 'C:/Users/rober/CLionProjects/test/cmake-build-debug'
"C:\Program Files\JetBrains\CLion 2018.2.6\bin\cmake\win\bin\cmake.exe" -SC:\Users\rober\CLionProjects\test -BC:\Users\rober\CLionProjects\test\cmake-build-debug --check-build-system CMakeFiles\Makefile.cmake 0
"C:\Program Files\JetBrains\CLion 2018.2.6\bin\cmake\win\bin\cmake.exe" -E cmake_progress_start C:\Users\rober\CLionProjects\test\cmake-build-debug\CMakeFiles 2
C:/MinGW/bin/mingw32-make.exe -f CMakeFiles\Makefile2 CMakeFiles/test.dir/all
mingw32-make.exe[2]: Entering directory 'C:/Users/rober/CLionProjects/test/cmake-build-debug'
C:/MinGW/bin/mingw32-make.exe -f CMakeFiles\test.dir\build.make CMakeFiles/test.dir/depend
mingw32-make.exe[3]: Entering directory 'C:/Users/rober/CLionProjects/test/cmake-build-debug'
"C:\Program Files\JetBrains\CLion 2018.2.6\bin\cmake\win\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Users\rober\CLionProjects\test C:\Users\rober\CLionProjects\test C:\Users\rober\CLionProjects\test\cmake-build-debug C:\Users\rober\CLionProjects\test\cmake-build-debug C:\Users\rober\CLionProjects\test\cmake-build-debug\CMakeFiles\test.dir\DependInfo.cmake --color=
Scanning dependencies of target test
mingw32-make.exe[3]: Leaving directory 'C:/Users/rober/CLionProjects/test/cmake-build-debug'
C:/MinGW/bin/mingw32-make.exe -f CMakeFiles\test.dir\build.make CMakeFiles/test.dir/build
mingw32-make.exe[3]: Entering directory 'C:/Users/rober/CLionProjects/test/cmake-build-debug'
[ 50%] Building C object CMakeFiles/test.dir/main.c.obj
C:\MinGW\bin\gcc.exe -Wall -Wextra -Wpedantic -g -std=gnu90 -o CMakeFiles\test.dir\main.c.obj -c C:\Users\rober\CLionProjects\test\main.c
C:\Users\rober\CLionProjects\test\main.c: In function 'main':
C:\Users\rober\CLionProjects\test\main.c:17:19: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char[23]' [-Wformat=]
printf("\n0: %s", func().string);
^
[100%] Linking C executable test.exe
"C:\Program Files\JetBrains\CLion 2018.2.6\bin\cmake\win\bin\cmake.exe" -E cmake_link_script CMakeFiles\test.dir\link.txt --verbose=1
"C:\Program Files\JetBrains\CLion 2018.2.6\bin\cmake\win\bin\cmake.exe" -E remove -f CMakeFiles\test.dir/objects.a
C:\MinGW\bin\ar.exe cr CMakeFiles\test.dir/objects.a @CMakeFiles\test.dir\objects1.rsp
C:\MinGW\bin\gcc.exe -Wall -Wextra -Wpedantic -g -Wl,--whole-archive CMakeFiles\test.dir/objects.a -Wl,--no-whole-archive -o test.exe -Wl,--out-implib,libtest.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles\test.dir\linklibs.rsp
mingw32-make.exe[3]: Leaving directory 'C:/Users/rober/CLionProjects/test/cmake-build-debug'
[100%] Built target test
mingw32-make.exe[2]: Leaving directory 'C:/Users/rober/CLionProjects/test/cmake-build-debug'
"C:\Program Files\JetBrains\CLion 2018.2.6\bin\cmake\win\bin\cmake.exe" -E cmake_progress_start C:\Users\rober\CLionProjects\test\cmake-build-debug\CMakeFiles 0
mingw32-make.exe[1]: Leaving directory 'C:/Users/rober/CLionProjects/test/cmake-build-debug'
Build finished
答案 0 :(得分:5)
在C90下func().string
不是左值,并且非左值数组也不会衰减到指针。
编译器只是告诉您:
C:\Users\rober\CLionProjects\test\main.c:17:19: warning: format '%s'
expects argument of type 'char *', but argument 2 has type 'char[23]'
[-Wformat=]
printf("\n0: %s", func().string);
这几乎使func().string
的任何非法使用都变为非法。不要那样做。
我没有一个很好的C90标准版本,但是据我收集,它应该在某处说出类似的意思:
3.2.2.1左值和函数指示符
[...]类型为“ T型数组”的左值被转换为类型为“ T型指针”的表达式,该表达式指向数组对象的初始成员[...]