当前位置:网站首页>The performance of nonstandard sprintf code in different platforms

The performance of nonstandard sprintf code in different platforms

2022-06-23 05:42:00 A little leisure

sprintf The use of format code is not standardized, and its performance on different platforms (C Language )


  author : Yu Han Gao
  Time :2022.6.22 10:09
  Blog :blog.csdn.net/cg_i

adults , Times have changed

 Insert picture description here

  Like many people, I study C Language is made up of 1978 year Dennis M. Ritchie and Brian W. Kernighan Co authored by 《The C Programming Language》 This book goes to C The world of language . First , The book describes C It's old-fashioned ( Sometimes called Kernighan and Ritchie[KERN 78], Or called K&R C) And has been ANSI C ( hereinafter referred to as standard ) It has fundamentally replaced . Although the vast majority of them are K&R C The program can be written in with very little modification ANSI C Environment is running , However, the standard does not stipulate that C The compiler checks for these differences , And most of them C The compiler does not check either . therefore , You must make sure that the code you write conforms to the specifications . If not used properly , They cause errors , Cause subtle and confusing symptoms , And it is extremely difficult to find the cause . It's very dangerous to use it with a little knowledge . In that case , It always brings pain, not joy .

Text

1. Usage environment

  • CPU

 HPUNIX: itanium 9700 series

 LINUX:X86 framework

  • operating system

 HPUNIX:HP-UX xxxxx2 B.11.31 U ia64 2932500072 unlimited-user license

 LINUX:Linux xxxxkf1 4.19.90-24.4.v2101.ky10.x86_64 #1 SMP Mon May 24 12:14:55 CST 2021 x86_64 x86_64 x86_64 GNU/Linux

  • Compiler program and version

 HPUNIX:cc: HP C/aC++ B3910B A.06.25 [Nov 30 2009]

 LINUX:

 Use built in  specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/7.3.0/lto-wrapper
 The goal is :x86_64-linux-gnu
 Configure to :../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,fortran,lto --enable-plugin --enable-initfini-array --disable-libgcj --without-isl --without-cloog --enable-gnu-indirect-function --build=x86_64-linux-gnu --with-stage1-ldflags=' -Wl,-z,relro,-z,now' --with-boot-ldflags=' -Wl,-z,relro,-z,now' --with-tune=generic --with-arch_32=x86-64 --disable-multilib
 Threading model :posix
gcc  edition  7.3.0 (GCC) 

2. Code display

  First look at the sample code :

#include<stdio.h>

int main(void)
{
  char sPNGZXH[100];
  int PNGZXH_LEN = 11;

  sprintf(sPNGZXH, "%0*s",PNGZXH_LEN,"123");
  printf("%s\n", sPNGZXH);
  return 0;
}
  • HPUNIX Compile and run
cc sp.c -o sp
./sp
00000000123
  • LINUX Compile and run
gcc sp.c -o sp
./sp
        123

sprintf

 int sprintf( char *buffer, char const *format, … );

 sprintf Take its result as a NUL The ending string is stored in the specified buffer Buffer instead of writing to the stream . The return value of the function is the actual number of characters printed or stored .

Warning

sprintf Is a potential source of error . The size of the buffer is not sprintf One of the parameters of the function , So if the output result is very long and overflows the buffer , It is possible to overwrite the data in the memory location behind the buffer . We should put an end to this problem , There are two strategies . The first 1 One is to declare a very large buffer , But this scheme is a waste of memory , And although large scour zones can reduce the likelihood of spillage , But this possibility cannot be eradicated . The first 2 One method is to analyze the format , See how long the result output will be after the maximum possible value is converted . for example , stay 4 On a bit integer machine , The largest integers are 11 position ( Include a sign bit ), So the buffer can at least hold 12 Characters ( Including the ending NUL byte ). There is no limit to the length of a string , However, the number of characters in the string generated by the function can be limited by an optional field in the formatting code .

Format code

 sprintf In the function prototype format The string may contain a format code , It formats the next value in the parameter list in the specified way , As for other characters, they are printed word for word . The format code starts with a percent sign , Followed by (1) Zero or more flag characters , Used to modify the execution mode of some transformations ,(2) An optional minimum field width ,(3) An optional precision ,(4) An optional modifier ,(5) Conversion type .

3. Problem description

  With the background above , Look at the output difference between the two platforms .HPUNIX The output under is what we have been using and want at present . However, the code is ported to LINUX Behind the platform , The original normal code ( Look like ) I can't use it now ( String right justified using 0 Fill in the left unused column , It becomes a space ).

  First, let's take a look at how the standard describes the symbol characters and their meanings ( Here are just the things we care about ).

Code Parameters meaning
schar * Print a string
sign meaning
0 When the value is right aligned , By default, unused columns are filled with spaces . This flag means to fill with zeros , It can be used for d,i,u,o,x,X,e,E,f,g and G Code . Use d,i,u,o,x and X Code , If the precision field is given , The zero flag is ignored . If a negative sign appears in the formatting code , The zero flag has no effect .
Width meaning
* The width is format ... is not specified in the string , But it will be placed as an additional integer value parameter before the parameter to be formatted .

summary

  Through careful study standard sign 0 It doesn't apply to s Code ,LINUX Just follow the standard strictly correct Output value in the format of , Instead, HPUNIX The output under is wrong . The root cause of this error : Is typically overly dependent on certain compiler features (HPUNIX Under the cc) Write non portable code . This will make it easier for the program to run in the future 、 Transplant and bury hidden dangers .

Reference resources

原网站

版权声明
本文为[A little leisure]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206230350276294.html