Rob*_*nau 6 c string printf struct
我一直遇到下面的代码问题,我想了解为什么它不起作用.当我直接在结构中使用一个从函数返回的字符串时,我得到了一个奇怪的行为.
第一个printf没有问题,与第二个和第三个相同,但由于某种原因,最后一个进入分段错误或只打印一个随机字符串.如果我尝试在结构中使用字符指针而不是数组,则问题不会出现.
#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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
====================[ 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
Run Code Online (Sandbox Code Playgroud)
在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);
Run Code Online (Sandbox Code Playgroud)
这几乎可以使用任何func().string非法行为.不要那样做.
我没有C90标准的好版本,但从我收集的内容来看,它应该在某个地方说出类似的内容:
3.2.2.1左值和函数指示符
[...]将类型为"T类型数组" 的左值转换为具有"指向类型T的指针"类型的表达式,该类型指向数组对象的初始成员[...]