Considerations for using variable length parameters in C language

Source: Internet
Author: User


The variable length parameter in C language greatly facilitates our programming, and it is also very easy to use inadvertently resulting in its hidden errors. Taking this function as an example, a segment error occurs randomly after a period of time, and the position of the error is stable in the vsprintf () function.

..................

A_listap;

Va_start (Ap,cmd);

..................

rep= (redisreply *) Redisvcommand (RC, CMD, AP);

VSPRINTF (Str,cmd, AP);

..................

Va_end (AP);


To delve into why, we downloaded the Redis source code and the glibc source code. See the implementation of Redisvcommand in the Redis source code:


Void*redisvcommand (Rediscontext *c, const char *format, va_list AP) {

if (Redisvappendcommand (c,format,ap)! = REDIS_OK)

Returnnull;

Return__redisblockforreply (c);

}


It mainly calls the Redisvappendcommand:


Intredisvappendcommand (Rediscontext *c, const char *format, va_list AP) {

Char*cmd;

Intlen;


len= Redisvformatcommand (&CMD,FORMAT,AP);

if (len = =-1) {

__redisseterror (C,redis_err_oom, "outof memory");

Returnredis_err;

}else if (len = =-2) {

__redisseterror (C,redis_err_other, "Invalidformat string");

Returnredis_err;

}


if (__redisappendcommand (c,cmd,len)! = REDIS_OK) {

Free (cmd);

Returnredis_err;

}


Free (cmd);

RETURNREDIS_OK;

}


In the Redisvappendcommand () function, Va_arg is used, such as the following part of the code:


The Newarg so it can checked even if it is nottouched. */

257 newarg = Curarg;

258

259 switch (c[1]) {

260 case ' s ':

261 arg = va_arg (ap,char*);

262 size = strlen (ARG);

263 if (Size > 0)

Newarg = Sdscatlen (curarg,arg,size);

265 break;

266 case ' B ':

267 arg = Va_arg (ap,char*);

268 size = Va_arg (ap,size_t);

269 if (Size > 0)

Newarg = Sdscatlen (curarg,arg,size);

271 break;

272 case '% ':

273 Newarg = Sdscat (curarg, "%");

274 break;

275 Default:


At first glance, the AP passes in the form parameter, will not change, but look closely va_arg's help document can see, in fact each call Va_arg () will change the value of the AP:


Va_arg ()

Theva_arg () macro expands to an expression of the type and valueof the next argument in the call.  The argument AP is the va_list ap initialized by Va_start (). Each call to Va_arg () modifies APS sothat the next call returns the next argument. The argument Typeis a

TypeName specified So, the type of a pointer to an object, hasthe specified type can be obtained simply by adding A * to type.


Thefirst use of the va_arg () macro after that of the Va_start () macroreturns the argument after last. Successive invocations return the

Valuesof the remaining arguments.


The AP is also passed in as a pointer pointer, so the variable-length parameter AP in the upper-call function changes, causing a segment error in the use of the variable-length parameter after it is encountered. Because the front has been traversed again, the AP to the end.

With this in mind, for a function to invoke the use of multiple variable-length parameters, a safe use is to assign a variable-length parameter va_list to each of the called functions individually. Accordingly, the above code should be rewritten like this:


A_listap;

Va_listaq;

Va_start (Ap,cmd);

Va_copy (AQ,AP);

.........

rep= (redisreply *) Redisvcommand (conn, CMD, AP);

vsprintf (Str,cmd, aq);

Va_end (AP);

Va_end (aq);

.........


This article is from the "Store Chef" blog, so be sure to keep this source http://xiamachao.blog.51cto.com/10580956/1951621

Considerations for using variable length parameters in C language

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.