7/25/2019 C faq programming
1/138
C FAQs
This article is always being improved. Your input is welcomed. Sendyour comments to [email protected] .
The questions answered here are divided into several categories:
1. Declarations and nitiali!ations". Structures# $nions# and %numerations&. %'pressions(. )ointers*. +ull )ointers,. -rrays and )ointers. /emory -llocation0. haracters and Strings
2. 3oolean %'pressions and 4ariables15. )reprocessor11. -+S6S7 Standard 1". Stdio1&. 8ibrary 9unctions1(. 9loating )oint1*. 4ariable8ength -rgument 8ists1,. Strange )roblems1. Style10. Tools and ;esources12. System Dependencies
"5. /iscellaneous
?erewith# some =requentlyasked questions and their answers:
Section 1. Declarations and nitiali!ations
1.1: ?ow do you decide which integer type to use
-: = you might need large values #use long. 7therwise# i= space is very important # use short. 7therwise# useint. = wellde=ined over=low characteristics are important andnegative values are not# or i= you want to steer clear o= signe'tension problems when manipulating bits or bytes# use one o=
7/25/2019 C faq programming
2/138
the corresponding unsigned types.
-lthough character types can be usedas AtinyA integers# doing so is sometimes more trouble than itBs
worth# due to unpredictable sign e'tension and increased codesi!e. # be sure to encapsulate the choice behindan appropriate typede=.
;e=erences: EF;1 Sec. "." p. &(C EF;" Sec. "." p. &,# Sec. -(."pp. 12*,# Sec. 311 p. "*C -+S Sec. ".".(.".1# Sec. &.1.".*CS7 Sec. *.".(.".1# Sec. ,.1.".*C ?FS Secs. *.1#*." pp. 11511(.
1.(: Ghat should the ,(bit type on new# ,(bit machines be
-: Some vendors o= products =or ,(bit machines support ,(bitlong ints. 7thers =ear that too much e'isting code is writtento assume that ints and longs are the same si!e# or that one orthe other o= them is e'actly &" bits# and introduce a new#nonstandard# ,(bit long long type instead.
)rogrammers interested in writing portable code should there=oreinsulate their ,(bit type needs behind appropriate typede=s.4endors who =eel compelled to introduce a new# longer integraltype should advertise it as being Aat least ,( bitsA # and not Ae'actly,( bits.A
;e=erences: -+S Sec. 9.*.,C S7 Sec. I.*.,.
1.: GhatBs the best way to declare and de=ine global variables
-: 9irst# though there can be many AdeclarationsA o= a single AglobalA
7/25/2019 C faq programming
3/138
allocates space# and provides an initiali!ation value# i= any.>The best arrangement is to place each de=inition in somerelevant .c =ile# with an e'ternal declaration in a header =ile# which is Jincluded wherever the declaration isneeded. The .c =ile containing the de=inition should also
Jinclude the same header =ile# so that the compiler can checkthat the de=inition matches the declarations.
This rule promotes a high degree o= portability: it isconsistent with the requirements o= the -+S Standard# and isalso consistent with most pre-+S compilers and linkers.
t is possible to use preprocessor tricks to arrange that a linelike
D%9+%C
need only be entered once in one header =ile# and turned into ade=inition or a declaration depending on the setting o= somemacro# but itBs not clear i= this is worth the trouble.
tBs especially important to put global declarations in header=iles i= you want the compiler to catch inconsistentdeclarations =or you. n particular# never place a prototype=or an e'ternal =unction in a .c =ile: it wouldnBt generally bechecked =or consistency with the de=inition# and an incompatibleprototype is worse than useless.
See also questions 15., and 10.0.
;e=erences: EF;1 Sec. (.* pp. ,C EF;" Sec. (.( pp. 051C -+SSec. &.1."."# Sec. &.# Sec. &.."# Sec. 9.*.11C S7Sec. ,.1."."# Sec. ,.# Sec. ,.."# Sec. I.*.11C ;ationaleSec. &.1."."C ?FS Sec. (.0 pp. 15115(# Sec. 2.".& p. ",C TF)Sec. (." pp. *(*,.
1.11: Ghat does e'tern mean in a =unction declaration
-: t can be used as a stylistic hint to indicate that the=unctionBs de=inition is probably in another source =ile# but
7/25/2019 C faq programming
4/138
there is no =ormal di==erence between
e'tern int =C
and
int =C
;e=erences: -+S Sec. &.1."."# Sec. &.*.1C S7 Sec. ,.1."."#Sec. ,.*.1C ;ationale Sec. &.1."."C ?FS Secs. (.(.&.1 pp. *,.
1.1": GhatBs the auto keyword good =or
-: +othingC itBs archaic. See also question "5.&.
;e=erences: EF;1 Sec. -0.1 p. 12&C -+S Sec. &.1.".(#Sec. &.*.1C S7 Sec. ,.1.".(# Sec. ,.*.1C ?FS Sec. (.& p. *#Sec. (.&.1 p. ,.
1.1(: canBt seem to de=ine a linked list success=ully. tried
typede= struct Kchar itemC+7D%)T; ne'tC
L +7D%)T;C
but the compiler gave me error messages. anBt a structure in contain a pointer to itsel=
-: Structures in can certainly contain pointers to themselvesCthe discussion and e'ample in section ,.* o= EF; make thisclear. The problem with the +7D%)T; e'ample is that the typede=has not been de=ined at the point where the Ane'tA =ield isdeclared. To =i' this code# =irst give the structure a tag. Then# declare the Ane'tA =ield as a simpleAstruct node A# or disentangle the typede= declaration =rom thestructure de=inition# or both. 7ne corrected version would be
struct node Kchar itemCstruct node ne'tC
LC
typede= struct node +7D%)T;C
7/25/2019 C faq programming
5/138
and there are at least three other equivalently correct ways o=arranging it.
- similar problem# with a similar solution# can arise whenattempting to declare a pair o= typede=Bed mutually re=erential
structures.
See also question ".1.
;e=erences: EF;1 Sec. ,.* p. 151C EF;" Sec. ,.* p. 1&2C -+SSec. &.*."# Sec. &.*.". esp. e'amplesC S7 Sec. ,.*."#Sec. ,.*.".&C ?FS Sec. *.,.1 pp. 1&"&.
1."1: ?ow do declare an array o= + pointers to =unctions returningpointers to =unctions returning pointers to characters
-: The =irst part o= this question can be answered in at leastthree ways:
1. char C
". 3uild the declaration up incrementally# using typede=s:
typede= char pcC 6 pointer to char 6typede= pc =pcC 6 =unction returning pointer to char 6typede= =pc p=pcC 6 pointer to above 6typede= p=pc =p=pcC 6 =unction returning... 6typede= =p=pc p=p=pcC6 pointer to... 6p=p=pc aM+NC 6 array o=... 6
&. $se the cdecl program# which turns %nglish into and vice versa:
cdeclO declare a as array o= pointer to =unction returningpointer to =unction returning pointer to char
char
cdecl can also e'plain complicated declarations# help with casts# and indicate which set o= parentheses the arguments go in . 4ersions o= cdecl are in volume 1( o= comp.sources.uni' and EF;".
-ny good book on should e'plain how to read these complicated declarations Ainside outA to understand them .
7/25/2019 C faq programming
6/138
The pointerto=unction declarations in the e'amples above havenot included parameter type in=ormation. Ghen the parametershave complicated types# declarations can really get messy.
;e=erences: EF;" Sec. *.1" p. 1""C -+S Sec. &.*== C S7 Sec. ,.*== C ?FS Sec. (.* pp.0*2"# Sec. *.15.1 pp. 1(2*5.
1."": ?ow can declare a =unction that can return a pointer to a=unction o= the same type Bm building a state machine withone =unction =or each state# each o= which returns a pointer tothe =unction =or the ne't state. 3ut canBt =ind a way todeclare the =unctions.
-: You canBt quite do it directly. %ither have the =unction returna generic =unction pointer# with some Pudicious casts to adPustthe types as the pointers are passed aroundC or have it return astructure containing only a pointer to a =unction returning thatstructure.
1."*: /y compiler is complaining about an invalid redeclaration o= a=unction# but only de=ine it once and call it once.
-: 9unctions which are called without a declaration in scope are assumed to be declared as returning int # leading to discrepanciesi= the =unction is later declared or de=ined otherwise. +onint=unctions must be declared be=ore they are called.
-nother possible source o= this problem is that the =unction hasthe same name as another one declared in some header =ile.
See also questions 11.& and 1*.1.
;e=erences: EF;1 Sec. (." p. 5C EF;" Sec. (." p. "C -+SSec. &.&."."C S7 Sec. ,.&."."C ?FS Sec. (. p. 151.
1.&5: Ghat can sa=ely assume about the initial values o= variableswhich are not e'plicitly initiali!ed = global variables startout as A!ero#A is that good enough =or null pointers and=loatingpoint !eroes
-: 4ariables with AstaticA duration
7/25/2019 C faq programming
7/138
outside o= =unctions# and those declared with the storage classstatic># are guaranteed initiali!ed to !ero# as i= the programmer had typed AQ 5A.There=ore# such variables are initiali!ed to the null pointer i= they are pointers#
and to 5.5 i= they are =loatingpoint.
4ariables with AautomaticA duration start out containing garbage#unless they are e'plicitly initiali!ed.
Dynamicallyallocated memory obtained with malloc andrealloc is also likely to contain garbage# and must beinitiali!ed by the calling program# as appropriate. /emoryobtained with calloc is allbits5# but this is not
necessarily use=ul =or pointer or =loatingpoint values .
;e=erences: EF;1 Sec. (.2 pp. 0"(C EF;" Sec. (.2 pp. 0*0,C-+S Sec. &.*.# Sec. (.15.&.1# Sec. (.15.*.&C S7 Sec. ,.*.#Sec. .15.&.1# Sec. .15.*.&C ?FS Sec. (.".0 pp. " Sec. (.,pp. 2" Sec. (.,." pp. 2(*# Sec. (.,.& p. 2,# Sec. 1,.1 p.&0,.
1.&1: This code# straight out o= a book# isnBt compiling:
=K
char aMN Q A?ello# worldRACL
-: )erhaps you have a pre-+S compiler# which doesnBt allowinitiali!ation o= Aautomatic aggregatesA . -s a workaround# you can makethe array global or static # or replace it with a pointer .
7/25/2019 C faq programming
8/138
char p Q Astring literalAC
/y program crashes i= try to assign a new value to pMiN.
-: - string literal can be used in two slightly di==erent ways. -s
an array initiali!er # itspeci=ies the initial values o= the characters in that array.-nywhere else# it turns into an unnamed# static array o=characters# which may be stored in readonly memory# which iswhy you canBt sa=ely modi=y it. n an e'pression conte't# thearray is converted at once to a pointer# as usual # so the second declaration initiali!es p to point to theunnamed arrayBs =irst element.
See also questions 1.&1# ,.1# ,."# and ,.0.
;e=erences: EF;" Sec. *.* p. 15(C -+S Sec. &.1.(# Sec. &.*.CS7 Sec. ,.1.(# Sec. ,.*.C ;ationale Sec. &.1.(C ?FS Sec. "..(pp. &1".
1.&(: =inally =igured out the synta' =or declaring pointers to=unctions# but now how do initiali!e one
-: $se something like
e'tern int =uncCint Q =uncC
Ghen the name o= a =unction appears in an e'pression like this#it AdecaysA into a pointer # much as an array name does.
-n e'plicit declaration =or the =unction is normally needed#since implicit e'ternal =unction declaration does not happen inthis case .
See also question (.1".
Section ". Structures# $nions# and %numerations
".1: GhatBs the di==erence between these two declarations
7/25/2019 C faq programming
9/138
struct '1 K ... LCtypede= struct K ... L '"C
-: The =irst =orm declares a Astructure tagAC the second declares a
Atypede=A. The main di==erence is that the second declarationis o= a slightly more abstract type its users donBtnecessarily know that it is a structure# and the keyword structis not used when declaring instances o= it.
".": Ghy doesnBt
struct ' K ... LC' thestructC
work
-: is not . Typede= names are not automatically generated =orstructure tags. See also question ".1 above.
".&: an a structure contain a pointer to itsel=
-: /ost certainly. See question 1.1(.
".(: GhatBs the best way o= implementing opaque data typesin
-: 7ne good way is =or clients to use structure pointers which point to structuretypes which are not publicly de=ined.
".,: came across some code that declared a structure like this:
struct name Kint namelenCchar namestrM1NC
LC
and then did some tricky allocation to make the namestr arrayact like it had several elements. s this legal or portable
-: This technique is popular# although Dennis ;itchie has called itAunwarranted chumminess with the implementation.A -n o==icialinterpretation has deemed that it is not strictly con=ormingwith the Standard.
7/25/2019 C faq programming
10/138
this list.> t does seem to be portable to all knownimplementations.
-nother possibility is to declare the variablesi!e element very
large# rather than very smallC in the case o= the above e'ample:
...char namestrM/-SU%NC...
where /-SU% is larger than any name which will be stored.?owever# it looks like this technique is disallowed by a strictinterpretation o= the Standard as well.
;e=erences: ;ationale Sec. &.*.(.".
".: heard that structures could be assigned to variables andpassed to and =rom =unctions# but EF;1 says not.
-: Ghat EF;1 said was that the restrictions on structure operationswould be li=ted in a =orthcoming version o= the compiler# and in=act structure assignment and passing were =ully =unctional in;itchieBs compiler even as EF;1 was being published. -lthough a=ew early compilers lacked these operations# all moderncompilers support them# and they are part o= the -+S standard# so there should be no reluctance to use them.
;e=erences: EF;1 Sec. ,." p. 1"1C EF;" Sec. ,." p. 1"2C -+SSec. &.1.".*# Sec. &.".".1# Sec. &.&.1,C S7 Sec. ,.1.".*#Sec. ,.".".1# Sec. ,.&.1,C ?FS Sec. *.,." p. 1&&.
".0: Ghy canBt you compare structures
-: There is no single# good way =or a compiler to implementstructure comparison which is consistent with Bs lowlevel=lavor. - simple bytebybyte comparison could =ounder onrandom bits present in unused AholesA in the structure . - =ieldby=ield comparison might requireunacceptable amounts o= repetitive code =or large structures.
7/25/2019 C faq programming
11/138
= you need to compare two structures# youBll have to write yourown =unction to do so# =ield by =ield.
;e=erences: EF;" Sec. ,." p. 1"2C -+S Sec. (.11.(.1 =ootnote1&,C ;ationale Sec. &.&.2C ?FS Sec. *.,." p. 1&&.
".2: ?ow are structure passing and returning implemented
-: Ghen structures are passed as arguments to =unctions# the entirestructure is typically pushed on the stack# using as many wordsas are required. Somecompilers merely pass a pointer to the structure# though theymay have to make a local copy to preserve passbyvaluesemantics.
Structures are o=ten returned =rom =unctions in a locationpointed to by an e'tra# compilersupplied AhiddenA argument tothe =unction. Some older compilers used a special# staticlocation =or structure returns# although this made structurevalued =unctions nonreentrant# which -+S disallows.
;e=erences: -+S Sec. ".".&C S7 Sec. *.".&.
".15: ?ow can pass constant values to =unctions which acceptstructure arguments
-: has no way o= generating anonymous structure values. You willhave to use a temporary structure variable or a little structurebuilding =unction.
7/25/2019 C faq programming
12/138
pointer values will be written# and they are most unlikely to bevalid when read back in. 9inally# note that =or widespreadportability you must use the AbA =lag when =opening the =ilesCsee question 1".&0.
- more portable solution# though itBs a bit more work initially#is to write a pair o= =unctions =or writing and reading astructure# =ieldby=ield# in a portable way.
;e=erences: ?FS Sec. 1*.1& p. &01.
".1": /y compiler is leaving holes in structures# which is wastingspace and preventing AbinaryA 67 to e'ternal data =iles. an turn o== the padding# or otherwise control the alignment o=structure =ields
-: Your compiler may provide an e'tension to give you this control
7/25/2019 C faq programming
13/138
This implementation is not 155W portableC some compilers maylegitimately re=use to accept it.
See question ".1* below =or a usage hint.
;e=erences: -+S Sec. (.1.*C S7 Sec. .1.,C ;ationaleSec. &.*.(."C ?FS Sec. 11.1 pp. "2"&.
".1*: ?ow can access structure =ields by name at run time
-: 3uild a table o= names and o==sets# using the o==seto= macro.The o==set o= =ield b in struct a is
o==setb Q o==seto=
= structp is a pointer to an instance o= this structure# and=ield b is an int # bBs value canbe set indirectly with
Q valueC
".10: This program works correctly# but it dumps core a=ter it=inishes. Ghy
struct list Kchar itemCstruct list ne'tC
L
6 ?ere is the main program. 6
mainK ... L
-: - missing semicolon causes main to be declared as returning astructure. Since structurevalued =unctions areusually implemented by adding a hidden return pointer
7/25/2019 C faq programming
14/138
-: -+S Standard allows an initiali!er =or the =irst member o= aunion. There is no standard way o= initiali!ing any othermember .
;e=erences: EF;" Sec. ,.0 pp. 1(02C -+S Sec. &.*.C S7Sec. ,.*.C ?FS Sec. (.,. p. 155.
"."": Ghat is the di==erence between an enumeration and a set o=preprocessor Jde=ines
-: -t the present time# there is little di==erence. -lthough manypeople might have wished otherwise# the Standard says thatenumerations may be =reely intermi'ed with other integral types#without errors.
Some advantages o= enumerations are that the numeric values areautomatically assigned# that a debugger may be able to displaythe symbolic values when enumeration variables are e'amined# andthat they obey block scope.
7/25/2019 C faq programming
15/138
aMiN Q iC
work
-: The sube'pression i causes a side e==ect it modi=ies iBsvalue which leads to unde=ined behavior since i is alsore=erenced elsewhere in the same e'pression. . n thee'ample# the compiler chose to multiply the previous value byitsel= and to per=orm both increments a=terwards.
The behavior o= code which contains multiple# ambiguous sidee==ects has always been unde=ined.
7/25/2019 C faq programming
16/138
protect you.A
;e=erences: EF;1 Sec. ".1" p. *5C EF;" Sec. ".1" p. *(C -+SSec. &.&C S7 Sec. ,.&C TF) Sec. &. p. (C )S Sec. 2.* pp.1"51.
&.&: Bve e'perimented with the code
M%+S7;%DN
on several compilers. Some gave i the value some gave (# butone gave . know the behavior is unde=ined# but how could itgive
-: M apologi!e =or the censorship o= the question# but thee'pression that used to be there was indecent# and by the
newlypassed ommunications Decency -ct o= the $.S.# amprohibited =rom transmitting AindecentA material# whatever thatis. Su==ice it to say that the e'pression tried to modi=y thesame variable twice between sequence points. scsN
$nde=ined behavior means anything can happen. See questions&.2 and 11.&&.
7/25/2019 C faq programming
17/138
Sec. ".1" pp. *" Sec. -. p. "55.
&.*: 3ut what about the FF and XX operators see code like AwhileA ...
-: There is a special e'ception =or those operators : le=ttoright evaluation is guaranteed . -ny book on should make this clear.
;e=erences: EF;1 Sec. "., p. &0# Secs. -.111" pp. 1251C EF;"Sec. "., p. (1# Secs. -.1(1* pp. "50C -+S Sec. &.&.1Sec. &.&.1(# Sec. &.&.1*C S7 Sec. ,.&.1 Sec. ,.&.1(#Sec. ,.&.1*C ?FS Sec. . pp. "10# Sec. .0 pp. "10"5#Sec. .1".1 p. ""2C TF) Sec. &. pp. (,.
&.0: ?ow can understand these comple' e'pressions GhatBs aAsequence pointA
-: - sequence point is the point
7/25/2019 C faq programming
18/138
aMiN Q iC
we donBt know which cell o= aMN gets written to# but i does getincremented by one.
-: +o. 7nce an e'pression or program becomes unde=ined# allaspects o= it become unde=ined. See questions &."# &. 11.&and 11.&*.
&.1": = Bm not using the value o= the e'pression# should use ior i to increment a variable
-: Since the two =orms di==er only in the value yielded# they areentirely equivalent when only their side e==ect is needed.
See also question &.&.
;e=erences: EF;1 Sec. ".0 p. (&C EF;" Sec. ".0 p. (C -+SSec. &.&.".(# Sec. &.&.&.1C S7 Sec. ,.&.".(# Sec. ,.&.&.1C ?FSSec. .(.( pp. 12" Sec. .*.0 pp. 122"55.
&.1(: Ghy doesnBt the code
int a Q 1555# b Q 1555Clong int c Q a bC
work
-: $nder Bs integral promotion rules# the multiplication iscarried out using int arithmetic# and the result may over=low orbe truncated be=ore being promoted and assigned to the long intle=thand side. $se an e'plicit cast to =orce long arithmetic:
long int c Q a bC
+ote that would not have the desired e==ect.
- similar problem can arise when two integers are divided# withthe result assigned to a =loatingpoint variable.
;e=erences: EF;1 Sec. ". p. (1C EF;" Sec. ". p. ((C -+SSec. &.".1.*C S7 Sec. ,.".1.*C ?FS Sec. ,.&.( p. 1,C TF)Sec. &.2 pp. (2*5.
&.1,: have a complicated e'pression which have to assign to one o=
7/25/2019 C faq programming
19/138
two variables# depending on a condition. an use code likethis
Q complicatedHe'pressionC
-: +o. The : operator# like most operators# yields a value# andyou canBt assign to a value. = you really want to# you can try something like
Q complicatedHe'pressionC
although this is admittedly not as pretty.
;e=erences: -+S Sec. &.&.1* esp. =ootnote *5C S7 Sec. ,.&.1*C?FS Sec. .1 pp. 12105.
Section (. )ointers
(.": Bm trying to declare a pointer and allocate some space =or it#but itBs not working. GhatBs wrong with this code
char pCp Q mallocC
-: The pointer you declared is p# not p. To make a pointer pointsomewhere# you Pust use the name o= the pointer:
p Q mallocC
tBs when youBre manipulating the pointedto memory that you use as an indirection operator:
p Q B?BC
See also questions 1."1# .1# and 0.&.
;e=erences: TF) Sec. &.1 p. "0.
(.&: Does p increment p# or what it points to
-: $nary operators like # # and all associate =romright to le=t. There=ore# p increments p . To increment thevalue pointed to by p# use .
7/25/2019 C faq programming
20/138
;e=erences: EF;1 Sec. *.1 p. 21C EF;" Sec. *.1 p. 2*C -+SSec. &.&."# Sec. &.&.&C S7 Sec. ,.&."# Sec. ,.&.&C ?FSSec. .(.( pp. 12" Sec. .* p. 12 Secs. .*.#.*.0 pp. 122"55.
(.*: have a char pointer that happens to point to some ints# and want to step it over them. Ghy doesnBt
C
work
-: n # a cast operator does not mean Apretend these bits have adi==erent type# and treat them accordinglyAC it is a conversionoperator# and by de=inition it yields an rvalue# which cannot be
assigned to# or incremented with . Say what you mean: use
p Q C
or simply
p Q si!eo=C
Ghenever possible# you should choose appropriate pointer typesin the =irst place# instead o= trying to treat one type asanother.
;e=erences: EF;" Sec. -.* p. "5*C -+S Sec. &.&.( C S7 Sec. ,.&.(C ;ationale Sec. &.&.".(C ?FSSec. .1 pp. 1205.
(.0: have a =unction which accepts# and is supposed to initiali!e#a pointer:
void =int ipCK
static int dummy Q *Cip Q FdummyC
L
3ut when call it like this:
7/25/2019 C faq programming
21/138
int ipC=C
the pointer in the caller remains unchanged.
-: -re you sure the =unction initiali!ed what you thought it did;emember that arguments in are passed by value. The called=unction altered only the passed copy o= the pointer. YouBlleither want to pass the address o= the pointer # or have the=unction return the pointer.
See also questions (.2 and (.11.
(.2: an use a void pointer to pass a generic pointer to a
=unction by re=erence
-: +ot portably. There is no generic pointertopointer type in .void acts as a generic pointer only because conversions areapplied automatically when other pointer types are assigned toand =rom void BsC these conversions cannot be per=ormed i= an attempt ismade to indirect upon a void value which points at somethingother than a void .
(.15: have a =unction
e'tern int =C
which accepts a pointer to an int. ?ow can pass a constant byre=erence - call like
=C
doesnBt seem to work.
-: You canBt do this directly. You will have to declare atemporary variable# and then pass its address to the =unction:
int =ive Q *C=C
See also questions ".15# (.0# and "5.1.
(.11: Does even have Apass by re=erenceA
7/25/2019 C faq programming
22/138
-: +ot really. Strictly speaking# always uses pass by value.You can simulate pass by re=erence yoursel=# by de=ining=unctions which accept pointers and then using the F operatorwhen calling# and the compiler will essentially simulate it =or
you when you pass an array to a =unction # but has nothing trulyequivalent to =ormal pass by re=erence or re=erenceparameters.
7/25/2019 C faq programming
23/138
;e=erences: EF;1 Sec. *.1" p. 11,C EF;" Sec. *.11 p. 1"5C -+SSec. &.&."."C S7 Sec. ,.&."."C ;ationale Sec. &.&."."C ?FSSec. *.0 p. 1(# Sec. .(.& p. 125.
Section *. +ull )ointers
*.1: Ghat is this in=amous null pointer# anyway
-: The language de=inition states that =or each pointer type# thereis a special value the Anull pointerA which isdistinguishable =rom all other pointer values and which isAguaranteed to compare unequal to a pointer to any obPect or=unction.A That is# the addresso= operator F will never yielda null pointer# nor will a success=ul call to malloc.
- null pointer is conceptually di==erent =rom an uninitiali!edpointer. - null pointer is known not to point to any obPect or=unctionC an uninitiali!ed pointer might point anywhere. Seealso questions 1.&5# .1# and .&1.
-s mentioned above# there is a null pointer =or each pointertype# and the internal values o= null pointers =or di==erenttypes may be di==erent. -lthough programmers need not know theinternal values# the compiler must always be in=ormed which typeo= null pointer is required# so that it can make the distinctioni= necessary
7/25/2019 C faq programming
24/138
char p Q 5Ci=
?owever# an argument being passed to a =unction is notnecessarily recogni!able as a pointer conte't# and the compilermay not be able to tell that an unadorned 5 AmeansA a nullpointer. To generate a null pointer in a =unction call conte't#an e'plicit cast may be required# to =orce the 5 to berecogni!ed as a pointer. 9or e'ample# the $ni' system calle'ecl takes a variablelength# nullpointerterminated list o=character pointer arguments# and is correctly called like this:
e'eclC
= the cast on the last argument were omitted# thecompiler would not know to pass a null pointer# and would passan integer 5 instead.
Ghen =unction prototypes are in scope# argument passing becomesan Aassignment conte't#A and most casts may sa=ely be omitted#since the prototype tells the compiler that a pointer isrequired# and o= which type# enabling it to correctly convert anunadorned 5. 9unction prototypes cannot provide the types =orvariable arguments in variablelength argument lists however# soe'plicit casts are still required =or those arguments. t is sa=est to properly cast all nullpointer constants in =unction calls: to guard against varargs=unctions or those without prototypes# to allow interim use o=non-+S compilers# and to demonstrate that you know what youare doing.
Summary:
$nadorned 5 okay: %'plicit cast required:
initiali!ation =unction call#no prototype in scope
assignmentvariable argument in
comparison varargs =unction call
=unction call#
7/25/2019 C faq programming
25/138
prototype in scope#=i'ed argument
;e=erences: EF;1 Sec. -. p. 125# Sec. -.1( p. 12"C EF;"Sec. -.15 p. "5# Sec. -.1 p. "52C -+S Sec. &.".".&C S7
Sec. ,.".".&C ?FS Sec. (.,.& p. 2*# Sec. ,.". p. 11.
*.&: s the abbreviated pointer comparison Ai=
A to test =or nonnull pointers valid Ghat i= the internal representation =ornull pointers is non!ero
-: Ghen requires the 3oolean value o= an e'pression # a =alse value is in=erred when the e'pressioncompares equal to !ero# and a true value otherwise. That is#whenever one writes
i= RQ 5>
Substituting the trivial pointer e'pression ApA =or Ae'pr#A wehave
i=
is equivalent to i=
and this is a comparison conte't# so the compiler can tell thatthe 5 is actually a null pointer constant# and usethe correct null pointer value. There is no trickery involvedhereC compilers do work this way# and generate identical code=or both constructs. The internal representation o= a nullpointer does not matter.
The boolean negation operator# R# can be described as =ollows:
Re'pr is essentially equivalent to QQ 5>
which leads to the conclusion that
i= is equivalent to i=
A-bbreviationsA such as i=
# though per=ectly legal# are
7/25/2019 C faq programming
26/138
considered by some to be bad style .
See also question 2.".
;e=erences: EF;" Sec. -.(. p. "5(C -+S Sec. &.&.&.Sec. &.&.2# Sec. &.&.1 Sec. &.&.1(# Sec. &.&.1*# Sec. &.,.(.1#Sec. &.,.*C S7 Sec. ,.&.&. Sec. ,.&.2# Sec. ,.&.1Sec. ,.&.1(# Sec. ,.&.1*# Sec. ,.,.(.1# Sec. ,.,.*C ?FSSec. *.&." p. 1"".
*.(: Ghat is +$88 and how is it Jde=ined
-: -s a matter o= style# many programmers pre=er not to haveunadorned 5Bs scattered through their programs. There=ore# thepreprocessor macro +$88 is Jde=ined
with the value 5# possibly cast to . - programmer who wishes to make e'plicit the distinctionbetween 5 the integer and 5 the null pointer constant can thenuse +$88 whenever a null pointer is required.
$sing +$88 is a stylistic convention onlyC the preprocessorturns +$88 back into 5 which is then recogni!ed by the compiler#in pointer conte'ts# as be=ore. n particular# a cast may stillbe necessary be=ore +$88 in a =unction callargument. The table under question *." above applies =or +$88as well as 5 .
+$88 should only be used =or pointersC see question *.2.
;e=erences: EF;1 Sec. *.( pp. 20C EF;" Sec. *.( p. 15"C -+SSec. (.1.*# Sec. &.".".&C S7 Sec. .1.,# Sec. ,.".".&C;ationale Sec. (.1.*C ?FS Sec. *.&." p. 1""# Sec. 11.1 p. "2".
*.*: ?ow should +$88 be de=ined on a machine which uses a non!ero bitpattern as the internal representation o= a null pointer
-: The same as on any other machine: as 5 .
Ghenever a programmer requests a null pointer# either by writingA5A or A+$88#A it is the compilerBs responsibility to generatewhatever bit pattern the machine uses =or that null pointer.There=ore# Jde=ining +$88 as 5 on a machine =or which internalnull pointers are non!ero is as valid as on any other: the
7/25/2019 C faq programming
27/138
compiler must always be able to generate the machineBs correctnull pointers in response to unadorned 5Bs seen in pointerconte'ts. See also questions *."# *.15# and *.1.
;e=erences: -+S Sec. (.1.*C S7 Sec. .1.,C ;ationale
Sec. (.1.*.
*.,: = +$88 were de=ined as =ollows:
Jde=ine +$88
wouldnBt that make =unction calls which pass an uncast +$88work
-: +ot in general. The problem is that there are machines whichuse di==erent internal representations =or pointers to di==erent
types o= data. The suggested de=inition would make uncast +$88arguments to =unctions e'pecting pointers to characters workcorrectly# but pointer arguments o= other types would still beproblematical# and legal constructions such as
98% =p Q +$88C
could =ail.
+evertheless# -+S allows the alternate de=inition
Jde=ine +$88
=or +$88. 3esides potentially helping incorrect programs towork # this de=inition may catchprograms which use +$88 incorrectly .
;e=erences: ;ationale Sec. (.1.*.
*.2: = +$88 and 5 are equivalent as null pointer constants# whichshould use
-: /any programmers believe that +$88 should be used in all pointerconte'ts# as a reminder that the value is to be thought o= as apointer. 7thers =eel that the con=usion surrounding +$88 and 5is only compounded by hiding 5 behind a macro# and pre=er to useunadorned 5 instead. There is no one right answer.
7/25/2019 C faq programming
28/138
+$88 and 5 are interchangeable in pointer conte'ts# and that anuncast 5 is per=ectly acceptable. -ny usage o= +$88 should be considered a gentle reminder that a pointer isinvolvedC programmers should not depend on it =or distinguishing pointer
5Bs =rom integer 5Bs.
+$88 should not be used when another kind o= 5 is required#even though it might work# because doing so sends the wrongstylistic message. generate nullpointers. +$88 is used only as a stylistic convention. Seequestions *.* and 2.".
*.1": use the preprocessor macro
Jde=ine +ullptr 5
to help me build null pointers o= the correct type.
-: This trick# though popular and super=icially attractive# doesnot buy much. t is not needed in assignments and comparisonsCsee question *.". t does not even save keystrokes. ts usemay suggest to the reader that the programBs author is shaky onthe subPect o= null pointers# requiring that the Jde=inition o=the macro# its invocations# and all other pointer usages bechecked. See also questions 2.1 and 15.".
7/25/2019 C faq programming
29/138
*.1&: This is strange. +$88 is guaranteed to be 5# but the nullpointer is not
-: Ghen the term AnullA or A+$88A is casually used# one o= several
things may be meant:
1. The conceptual null pointer# the abstract language conceptde=ined in question *.1. t is implemented with...
". The internal representation o= a nullpointer# which may or may not be allbits5 and which maybe di==erent =or di==erent pointer types. The actualvalues should be o= concern only to compiler writers.-uthors o= programs never see them# since they use...
&. The null pointer constant# which is a constant integer 5
7/25/2019 C faq programming
30/138
construct Ai=
A is easily misread as calling =orconversion o= p to an integral type# rather than 5 to a pointertype# be=ore the comparison. 9inally# the distinction betweenthe several uses o= the term AnullA is o=ten overlooked.
7ne good way to wade out o= the con=usion is to imagine that used a keyword as a null pointerconstant. The compiler could either turn AnilA into the correcttype o= null pointer when it could determine the type =rom thesource code# or complain when it could not. +ow in =act# in the keyword =or a null pointer constant is not AnilA but A5A#which works almost as well# e'cept that an uncast A5A in a nonpointer conte't generates an integer !ero instead o= an errormessage# and i= that uncast 5 was supposed to be a null pointerconstant# the code may not work.
*.1*: Bm con=used. Pust canBt understand all this null pointerstu==.
-: 9ollow these two simple rules:
1. Ghen you want a null pointer constant in source code#use A5A or A+$88A.
". = the usage o= A5A or A+$88A is an argument in a=unction call# cast it to the pointer type e'pected bythe =unction being called.
The rest o= the discussion has to do with other peopleBsmisunderstandings# with the internal representation o= nullpointers # and with -+S re=inements. $nderstand questions *.1# *."# and *.(# andconsider *. *.2# *.1 and *.1(# and youBll do =ine.
*.1,: Iiven all the con=usion surrounding null pointers# wouldnBt itbe easier simply to require them to be represented internally by!eroes
-: = =or no other reason# doing so would be illadvised because itwould unnecessarily constrain implementations which wouldotherwise naturally represent null pointers by special# non!erobit patterns# particularly when those values would triggerautomatic hardware traps =or invalid accesses.
3esides# what would such a requirement really accomplish
7/25/2019 C faq programming
31/138
)roper understanding o= null pointers does not require knowledgeo= the internal representation# whether !ero or non!ero.-ssuming that null pointers are internally !ero does not makeany code easier to write as a nullpointer.
7/25/2019 C faq programming
32/138
Depending on the Amemory modelA in use# 050,=amily processors may use 1,bit data pointers and &"bit=unction pointers# or vice versa.
Some ,(bit ray machines represent int in the lower (0 bitso= a wordC char additionally uses the upper 1, bits toindicate a byte address within a word.
;e=erences: EF;1 Sec. -1(.( p. "11.
*."5: Ghat does a runtime Anull pointer assignmentA error mean ?owdo track it down
-: This message# which typically occurs with /SD7S compilers means that youBve written# via a null
pointer# to location 5.
- debugger may let you set a data breakpoint or watchpoint orsomething on location 5. -lternatively# you could write a bito= code to stash away a copy o= "5 or so bytes =rom location 5#and periodically check that the memory at location 5 hasnBtchanged.
Section ,. -rrays and )ointers
,.1: had the de=inition char aM,N in one source =ile# and inanother declared e'tern char a. Ghy didnBt it work
-: The declaration e'tern char a simply does not match the actualde=inition. The type pointertotypeT is not the same as arrayo=typeT. $se e'tern char aMN.
;e=erences: -+S Sec. &.*.(."C S7 Sec. ,.*.(."C TF) Sec. &.&pp. &&(# Sec. (.* pp. ,(*.
,.": 3ut heard that char aMN was identical to char a.
-: +ot at all. -rrays are not pointers. Thearray declaration char aM,N requests that space =or si'characters be set aside# to be known by the name Aa.A That is#there is a location named AaA at which si' characters can sit.The pointer declaration char p# on the other hand# requests a
7/25/2019 C faq programming
33/138
place which holds a pointer# to be known by the name Ap.A Thispointer can point almost anywhere: to any char# or to anycontiguous array o= chars# or nowhere .
-s usual# a picture is worth a thousand words. The declarations
char aMN Q AhelloACchar p Q AworldAC
would initiali!e data structures which could be represented likethis:
a: X h X e X l X l X o XV5 X
p: X QQQQQQO X w X o X r X l X d XV5 X
t is important to reali!e that a re=erence like 'M&Ngenerates di==erent code depending on whether ' is an array ora pointer. Iiven the declarations above# when the compiler seesthe e'pression aM&N# it emits code to start at the location Aa#Amove three past it# and =etch the character there. Ghen it seesthe e'pression pM&N# it emits code to start at the location Ap#A=etch the pointer value there# add three to the pointer# and=inally =etch the character pointed to. n other words# aM&N isthree places past the obPect named a# whilepM&N is three places past the obPect pointed to by p. n thee'ample above# both aM&N and pM&N happen to be the characterBlB# but the compiler gets there di==erently.
;e=erences: EF;" Sec. *.* p. 15(C TF) Sec. (.* pp. ,(*.
,.&: So what is meant by the Aequivalence o= pointers and arraysA in
-: /uch o= the con=usion surrounding arrays and pointers in canbe traced to a misunderstanding o= this statement. Saying thatarrays and pointers are AequivalentA means neither that they areidentical nor even interchangeable.
A%quivalenceA re=ers to the =ollowing key de=inition:
-n lvalue o= type arrayo=T which appears in ane'pression decays
7/25/2019 C faq programming
34/138
pointer to its =irst elementC the type o= theresultant pointer is pointertoT.
7/25/2019 C faq programming
35/138
=char aCK ... L
This conversion holds only within =unction =ormal parameterdeclarations# nowhere else. = the conversion bothers you#avoid itC many people have concluded that the con=usion itcauses outweighs the small advantage o= having the declarationAlook likeA the call or the uses within the =unction.
See also question ,."1.
;e=erences: EF;1 Sec. *.& p. 2*# Sec. -15.1 p. "5*C EF;"Sec. *.& p. 155# Sec. -0.,.& p. "10# Sec. -15.1 p. "",C -+SSec. &.*.(. Sec. &..1# Sec. &.2.,C S7 Sec. ,.*.(.
Sec. ,..1# Sec. ,.2.,C ?FS Sec. 2.& p. "1C TF) Sec. &.& pp.&&(.
,.: ?ow can an array be an lvalue# i= you canBt assign to it
-: The -+S Standard de=ines a Amodi=iable lvalue#A which anarray is not.
;e=erences: -+S Sec. &.".".1C S7 Sec. ,.".".1C ;ationaleSec. &.".".1C ?FS Sec. .1 p. 12.
,.0: )ractically speaking# what is the di==erence between arrays andpointers
-: -rrays automatically allocate space# but canBt be relocated orresi!ed. )ointers must be e'plicitly assigned to point toallocated space # but can be reassigned at will# and have many otheruses besides serving as the base o= blocks o= memory.
Due to the socalled equivalence o= arrays and pointers # arrays and pointers o=ten seem interchangeable#and in particular a pointer to a block o= memory assigned bymalloc is =requently treated e'actly as i= it were a true array. See questions ,.1( and,.1,.
See also questions 1.&" and "5.1(.
,.2: Someone e'plained to me that arrays were really Pust constant
7/25/2019 C faq programming
36/138
pointers.
-: This is a bit o= an oversimpli=ication. -n array name isAconstantA in that it cannot be assigned to# but an array isnot a pointer# as the discussion and pictures in question ,."
should make clear. See also questions ,.& and ,.0.
,.11: came across some APokeA code containing the Ae'pressionA*MAabcde=AN . ?ow can this be legal
-: Yes# 4irginia# array subscripting is commutative in . Thiscurious =act =ollows =rom the pointer de=inition o= arraysubscripting# namely that aMeN is identical to # =orany two e'pressions a and e# as long as one o= them is apointer e'pression and one is integral. This unsuspectedcommutativity is o=ten mentioned in te'ts as i= it were
something to be proud o=# but it =inds no use=ul applicationoutside o= the 7b=uscated ontest
7/25/2019 C faq programming
37/138
subscripting or incrementing the resultant pointer will accessthe individual members o= the array. True pointers to arrays#when subscripted or incremented# step over entire arrays# andare generally use=ul only when operating on arrays o= arrays# i=at all.
= you really need to declare a pointer to an entire array# usesomething like Aint M+NCA where + is the si!e o= the array.
7/25/2019 C faq programming
38/138
initiali!e each pointer to a dynamicallyallocated Arow.A ?ereis a twodimensional e'ample:
Jinclude
int array1 Q mallocC=orarray1MiN Q mallocC
You can keep the arrayBs contents contiguous# while making laterreallocation o= individual rows di==icult# with a bit o=e'plicit pointer arithmetic:
int array" Q mallocCarray"M5N Q mallocC=or
array"MiN Q array"M5N i ncolumnsC
n either case# the elements o= the dynamic array can beaccessed with normallooking array subscripts: array'MiNMPN .
= the double indirection implied by the above schemes is =orsome reason unacceptable# you can simulate a twodimensionalarray with a single# dynamicallyallocated onedimensionalarray:
int array& Q mallocC
?owever# you must now per=orm subscript calculations manually#accessing the i#Pth element with array&Mi ncolumns PN.
7/25/2019 C faq programming
39/138
may be speci=ied at run time.
Gith all o= these techniques# you may o= course need to rememberto =ree the arrays .
-ll o= these techniques can also be e'tended to three or moredimensions.
,.1: ?ereBs a neat trick: i= write
int realarrayM15NCint array Q FrealarrayM1NC
can treat AarrayA as i= it were a 1based array.
-: -lthough this technique is attractive # it does notcon=orm to the standards. )ointer arithmetic is de=ined onlyas long as the pointer points within the same allocated block o=memory# or to the imaginary AterminatingA element one past itCotherwise# the behavior is unde=ined# even i= the pointer isnot dere=erenced. The code above could =ail i=# whilesubtracting the o==set# an illegal address were generated.
;e=erences: EF;" Sec. *.& p. 155# Sec. *.( pp. 15" Sec. -.pp. "5*,C -+S Sec. &.&.,C S7 Sec. ,.&.,C ;ationaleSec. &.".".&.
,.10: /y compiler complained when passed a twodimensional array toa =unction e'pecting a pointer to a pointer.
-: The rule by which arrays decay into pointersis not applied recursively. -n array o= arrays decays into a pointer to an array# not apointer to a pointer. )ointers to arrays can be con=using# andmust be treated care=ullyC see also question ,.1&.
7/25/2019 C faq programming
40/138
= you are passing a twodimensional array to a =unction:
int arrayM+;7GSNM+78$/+SNC=C
the =unctionBs declaration must match:
=K ... L
or
= 6 ap is a pointer to an array 6K ... L
n the =irst declaration# the compiler per=orms the usualimplicit parameter rewriting o= Aarray o= arrayA to Apointer toarrayA C in the second =orm thepointer declaration is e'plicit. Since the called =unction doesnot allocate space =or the array# it does not need to know theoverall si!e# so the number o= rows# +;7GS# can be omitted. TheAshapeA o= the array is still important# so the column dimension+78$/+S must be retained.
= a =unction is already declared as accepting a pointer to apointer# it is probably meaningless to pass a twodimensionalarray directly to it.
See also questions ,.1" and ,.1*.
;e=erences: EF;1 Sec. *.15 p. 115C EF;" Sec. *.2 p. 11&C ?FSSec. *.(.& p. 1",.
,.12: ?ow do write =unctions which accept twodimensional arrayswhen the AwidthA is not known at compile time
-: tBs not easy. 7ne way is to pass in a pointer to the M5NM5Nelement# along with the two dimensions# and simulate arraysubscripting Aby hand:A
="int arypCint nrows# ncolumnsCK ... arrayMiNMPN is accessed as arypMi ncolumns PN ... L
7/25/2019 C faq programming
41/138
This =unction could be called with the array =rom question ,.10as
="C
t must be noted# however# that a program which per=ormsmultidimensional array subscripting Aby handA in this way is notin strict con=ormance with the -+S StandardC according to ano==icial interpretation# the behavior o= accessingM'N is not de=ined =or ' OQ +78$/+S.
gcc allows local arrays to be declared having si!es which arespeci=ied by a =unctionBs arguments# but this is a nonstandarde'tension.
Ghen you want to be able to use a =unction on multidimensionalarrays o= various si!es# one solution is to simulate all thearrays dynamically# as in question ,.1,.
See also questions ,.10# ,."5# and ,.1*.
;e=erences: -+S Sec. &.&.,C S7 Sec. ,.&.,.
,."5: ?ow can use statically and dynamicallyallocatedmultidimensional arrays interchangeably when passing them to=unctions
-: There is no single per=ect method. Iiven the declarations
int arrayM+;7GSNM+78$/+SNCint array1C 6 ragged 6int array"C 6 contiguous 6int array&C 6 A=lattenedA 6int M+78$/+SNC
with the pointers initiali!ed as in the code =ragments inquestion ,.1,# and =unctions declared as
=1C="C=&C
where =1 accepts a conventional twodimensional array# ="accepts a A=lattenedA twodimensional array# and =& accepts apointertopointer# simulated array
7/25/2019 C faq programming
42/138
,.12># the =ollowing calls should work as e'pected:
=1C=1C="C
="C="C
The =ollowing two calls would probably work on most systems# butinvolve questionable casts# and work only i= the dynamicncolumns matches the static +78$/+S:
=1
7/25/2019 C faq programming
43/138
.1: Ghy doesnBt this =ragment work
char answerCprint=C
getsCprint=C
-: The pointer variable answer# which is handed to gets as thelocation into which the response should be stored# has not beenset to point to any valid storage. That is# we cannot say wherethe pointer answer points.
The simplest way to correct the questionasking program is touse a local array# instead o= a pointer# and let the compilerworry about allocation:
JincludeJinclude
char answerM155N# pCprint=C=getsCi=
p Q BV5BCprint=C
This e'ample also uses =gets instead o= gets# so that theend o= the array cannot be overwritten.
7/25/2019 C faq programming
44/138
not provide an automaticallymanaged string type. compilersonly allocate memory =or obPects e'plicitly mentioned in thesource code . The programmer must arrange =orsu==icient space =or the results o= runtime operations such as
string concatenation# typically by declaring arrays# or bycalling malloc.
strcat per=orms no allocationC the second string is appendedto the =irst one# in place. There=ore# one =i' would be todeclare the =irst string as an array:
char s1M"5N Q A?ello# AC
Since strcat returns the value o= its =irst argument # the variable s& is super=luous.
The original call to strcat in the question actually has twoproblems: the string literal pointed to by s1# besides not beingbig enough =or any concatenated te't# is not necessarilywritable at all. See question 1.&".
;e=erences: TF) Sec. &." p. &".
.&: 3ut the man page =or strcat says that it takes two char Bs asarguments. ?ow am supposed to know to allocate things
-: n general# when using pointers you always have to considermemory allocation# i= only to make sure that the compiler isdoing it =or you. = a library =unctionBs documentation doesnot e'plicitly mention allocation# it is usually the callerBsproblem.
The Synopsis section at the top o= a $ni'style man page or inthe -+S standard can be misleading. The code =ragmentspresented there are closer to the =unction de=initions used byan implementor than the invocations used by the caller. nparticular# many =unctions which accept pointers are usually called with the address o=some obPect . 7ther common e'amples are time
7/25/2019 C faq programming
45/138
-: /ake sure that the pointedto memory is properly allocated. Thereturned pointer should be to a staticallyallocated bu==er# orto a bu==er passed in by the caller# or to memory obtained withmalloc# but not to a local array. n otherwords# never do something like
char itoaK
char retbu=M"5NC 6 G;7+I 6sprint=Creturn retbu=C 6 G;7+I 6
L
7ne =i' would be to declare the return
bu==er as
static char retbu=M"5NC
See also questions 1"."1 and "5.1.
;e=erences: -+S Sec. &.1.".(C S7 Sec. ,.1.".(.
.,: Ghy am getting Awarning: assignment o= pointer =rom integerlacks a castA =or calls to malloc
-: ?ave you Jincluded # or otherwise arranged =ormalloc to be declared properly
;e=erences: ?FS Sec. (. p. 151.
.: Ghy does some code care=ully cast the values returned by mallocto the pointer type being allocated
-: 3e=ore -+S6S7 Standard introduced the void generic pointertype# these casts were typically required to silence warnings when assigning betweenincompatible pointer types.
;e=erences: ?FS Sec. 1,.1 pp. &0,.
.0: see code like
char p Q mallocC
7/25/2019 C faq programming
46/138
strcpyC
ShouldnBt that be malloc
-: tBs never necessary to multiply by si!eo=# since
si!eo= is# by de=inition# e'actly 1.
7/25/2019 C faq programming
47/138
See also question 12."&.
.12: /y program is crashing# apparently somewhere down inside malloc#but canBt see anything wrong with it.
-: t is un=ortunately very easy to corrupt mallocBs internal datastructures# and the resulting problems can be stubborn. Themost common source o= problems is writing more to a mallocBedregion than it was allocated to holdC a particularly common bugis to malloc instead o= strlen 1. 7therproblems may involve using pointers to =reed storage# =reeingpointers twice# =reeing pointers not obtained =rom malloc# ortrying to realloc a null pointer .
See also questions .",# 1,.0# and 10.".
."5: You canBt use dynamicallyallocated memory a=ter you =ree it#can you
-: +o. Some early documentation =or malloc stated that thecontents o= =reed memory were Ale=t undisturbed#A but this illadvised guarantee was never universal and is not required by the Standard.
9ew programmers would use the contents o= =reed memorydeliberately# but it is easy to do so accidentally. onsiderthe =ollowing code =or =reeing a singlylinked list:
struct list listp# ne'tpC=or
7/25/2019 C faq programming
48/138
-: Ghen you call =ree# the memory pointed to by the passedpointer is =reed# but the value o= the pointer in the callerremains unchanged# because Bs passbyvalue semantics mean thatcalled =unctions never permanently change the values o= theirarguments.
- pointer value which has been =reed is# strictly speaking#invalid# and any use o= it# even i= is not dere=erenced cantheoretically lead to trouble# though as a quality o=implementation issue# most implementations will probably not goout o= their way to generate e'ceptions =or innocuous uses o=invalid pointers.
;e=erences: -+S Sec. (.15.&C S7 Sec. .15.&C ;ationaleSec. &.".".&.
."": Ghen call malloc to allocate memory =or a local pointer# do have to e'plicitly =ree it
-: Yes. ;emember that a pointer is di==erent =rom what it pointsto. 8ocal variables are deallocated when the =unction returns#but in the case o= a pointer variable# this means that thepointer is deallocated# not what it points to. /emoryallocated with malloc always persists until you e'plicitly=ree it. n general# =or every call to malloc# there shouldbe a corresponding call to =ree.
."&: Bm allocating structures which contain pointers to otherdynamicallyallocated obPects. Ghen =ree a structure# do have to =ree each subsidiary pointer =irst
-: Yes. n general# you must arrange that each pointer returned=rom malloc be individually passed to =ree# e'actly once .
- good rule o= thumb is that =or each call to malloc in aprogram# you should be able to point at the call to =ree which=rees the memory allocated by that malloc call.
See also question ."(.
."(: /ust =ree allocated memory be=ore the program e'its
-: You shouldnBt have to. - real operating system de=initivelyreclaims all memory when a program e'its. +evertheless# somepersonal computers are said not to reliably recover memory# and
7/25/2019 C faq programming
49/138
all that can be in=erred =rom the -+S6S7 Standard is thatthis is a Aquality o= implementation issue.A
;e=erences: -+S Sec. (.15.&."C S7 Sec. .15.&.".
."*: have a program which mallocs and later =rees a lot o= memory#but memory usage doesnBt seem to go backdown.
-: /ost implementations o= malloc6=ree do not return =reed memoryto the operating system # but merely make itavailable =or =uture malloc calls within the same program.
.",: ?ow does =ree know how many bytes to =ree
-: The malloc6=ree implementation remembers the si!e o= each block
allocated and returned# so it is not necessary to remind it o=the si!e when =reeing.
.": So can query the malloc package to =ind out how big anallocated block is
-: +ot portably.
.&5: s it legal to pass a null pointer as the =irst argument torealloc Ghy would you want to
-: -+S sanctions this usage # although several earlier implementations do notsupport it# so it may not be =ully portable. )assing aninitiallynull pointer to realloc can make it easier to writea sel=starting incremental allocation algorithm.
;e=erences: -+S Sec. (.15.&.(C S7 Sec. .15.&.(C ?FS Sec. 1,.&p. &00.
.&1: GhatBs the di==erence between calloc and malloc s it sa=eto take advantage o= callocBs !ero=illing Does =ree workon memory allocated with calloc# or do you need a c=ree
-: calloc is essentially equivalent to
p Q mallocCmemsetC
The !ero =ill is allbits!ero# and does not there=ore
7/25/2019 C faq programming
50/138
guarantee use=ul null pointer values or =loatingpoint !ero values. =ree is properly used to=ree the memory allocated by calloc.
;e=erences: -+S Sec. (.15.& to (.15.&."C S7 Sec. .15.& to
.15.&."C ?FS Sec. 1,.1 p. &0,# Sec. 1,." p. &0,C )S Sec. 11pp. 1(1#1(".
.&": Ghat is alloca and why is its use discouraged
-: alloca allocates memory which is automatically =reed when the=unction which called alloca returns. That is# memoryallocated with alloca is local to a particular =unctionBs Astack=rameA or conte't.
alloca cannot be written portably# and is di==icult to
implement on machines without a conventional stack. ts use isproblematical when its return value is passed directly toanother =unction# as in =gets.
9or these reasons# alloca is not Standard and cannot be usedin programs which must be widely portable# no matter how use=ulit might be.
See also question ."".
;e=erences: ;ationale Sec. (.15.&.
Section 0. haracters and Strings
0.1: Ghy doesnBt
strcatC
work
-: There is a very real di==erence between characters and strings#and strcat concatenates strings.
haracters in are represented by small integers correspondingto their character set values .Strings are represented by arrays o= charactersC you usuallymanipulate a pointer to the =irst character o= the array. t isnever correct to use one when the other is e'pected. To append
7/25/2019 C faq programming
51/138
a R to a string# use
strcatC
See also questions 1.&"# ."# and 1,.,.
;e=erences: TF) Sec. 1.* pp. 215.
0.": Bm checking a string to see i= it matches a particular value.Ghy isnBt this code working
char stringC...i= K
6 string matches AvalueA 6...
L
-: Strings in are represented as arrays o= characters# and never manipulates arrays as a whole.The QQ operator in the code =ragment above compares two pointers the value o= the pointer variable string and a pointer to thestring literal AvalueA to see i= they are equal# that is# i=they point to the same place. They probably donBt# so thecomparison never succeeds.
To compare two strings# you generally use the library =unctionstrcmp:
i= K6 string matches AvalueA 6...
L
0.&: = can say
char aMN Q A?ello# worldRAC
why canBt say
char aM1(NCa Q A?ello# worldRAC
-: Strings are arrays# and you canBt assign arrays directly. $sestrcpy instead:
7/25/2019 C faq programming
52/138
strcpyC
See also questions 1.&"# (."# and .".
0.,: ?ow can get the numeric value corresponding to
a character# or vice versa
-: n # characters are represented by small integers correspondingto their values # so you donBtneed a conversion routine: i= you have the character# you haveits value.
0.2: think somethingBs wrong with my compiler: Pust noticed thatsi!eo= is "# not 1 .
-: )erhaps surprisingly# character constants in are o= type int#
so si!eo= is si!eo= .See also question .0.
;e=erences: -+S Sec. &.1.&.(C S7 Sec. ,.1.&.(C ?FS Sec. "..&p. "2.
Section 2. 3oolean %'pressions
2.1: Ghat is the right type to use =or 3oolean values in GhyisnBt it a standard type Should use Jde=ines or enums =orthe true and =alse values
-: does not provide a standard 3oolean type# in part becausepicking one involves a space6time tradeo== which can best bedecided by the programmer.
The choice between Jde=ines and enumeration constants =or thetrue6=alse values is arbitrary and not terribly interesting
7/25/2019 C faq programming
53/138
program or proPect.
7/25/2019 C faq programming
54/138
;e=erences: EF;1 Sec. "., p. &2# Sec. ". p. (1C EF;" Sec. ".,p. ("# Sec. ". p. ((# Sec. -.(. p. "5(# Sec. -.2 p. "5,C-+S Sec. &.&.&. Sec. &.&.0# Sec. &.&.2# Sec. &.&.1Sec. &.&.1(# Sec. &.&.1*# Sec. &.,.(.1# Sec. &.,.*C S7
Sec. ,.&.&. Sec. ,.&.0# Sec. ,.&.2# Sec. ,.&.1 Sec. ,.&.1(#Sec. ,.&.1*# Sec. ,.,.(.1# Sec. ,.,.*C ?FS Sec. .*.( pp. 12,#Sec. .,.( pp. "50# Sec. .,.* pp. "502# Sec. . pp. "10#Sec. .0 pp. "102# Sec. 0.* pp. "&02# Sec. 0., pp. "(1(CAGhat the Tortoise Said to -chillesA.
2.&: s i=
# where p is a pointer# a valid conditional
-: Yes. See question *.&.
Section 15. )reprocessor
15.": ?ere are some cute preprocessor macros:
Jde=ine begin KJde=ine end L
Ghat do yBall think
-: 3leah. See also section 1.
15.&: ?ow can write a generic macro to swap two values
-: There is no good answer to this question. = the values areintegers# a wellknown trick using e'clusive7; could perhaps beused# but it will not work =or =loatingpoint values orpointers# or i= the two values are the same variable
7/25/2019 C faq programming
55/138
-: The usual goal is to write a macro that can be invoked as i= itwere a statement consisting o= a single =unction call. Thismeans that the AcallerA will be supplying the =inal semicolon#so the macro body should not. The macro body cannot there=ore
be a simple braceenclosed compound statement# because synta'errors would result i= it were invoked
7/25/2019 C faq programming
56/138
tBs especially important to put a declaration or de=inition ina header =ile when it will be shared between several other=iles.
7/25/2019 C faq programming
57/138
Typically# headers named with O synta' are searched =or in oneor more standard places. ?eader =iles named with AA synta' are=irst searched =or in the Acurrent directory#A then in the same standard places.
Traditionally
7/25/2019 C faq programming
58/138
-: +o. )reprocessing happens during an earlier phase o=compilation# be=ore type names have been parsed. nstead o=si!eo=# consider using the prede=ined constants in -+SBs# i= applicable# or perhaps a Acon=igureA script.
;e=erences: -+S Sec. ".1.1."# Sec. &.0.1 =ootnote 0&C S7Sec. *.1.1."# Sec. ,.0.1C ?FS Sec. .11.1 p. ""*.
15.1(: an use an Ji=de= in a Jde=ine line# to de=ine something twodi==erent ways
-: +o. You canBt Arun the preprocessor on itsel=#A so to speak.Ghat you can do is use one o= two completely separate Jde=inelines# depending on the Ji=de= setting.
;e=erences: -+S Sec. &.0. Sec. &.0.&.(C S7 Sec. ,.0.Sec. ,.0.&.(C ?FS Sec. &." pp. (51.
15.1*: s there anything like an Ji=de= =or typede=s
-: $n=ortunately# no.
;e=erences: -+S Sec. ".1.1."# Sec. &.0.1 =ootnote 0&C S7Sec. *.1.1."# Sec. ,.0.1C ?FS Sec. .11.1 p. ""*.
15.1,: ?ow can use a preprocessor Ji= e'pression to tell i= a machineis bigendian or littleendian
-: You probably canBt. -re yousure you need to know the machineBs endianness e'plicitly$sually itBs better to write code which doesnBt care >. Seealso question "5.2.
;e=erences: -+S Sec. &.0.1C S7 Sec. ,.0.1C ?FS Sec. .11.1p. ""*.
15.10: inherited some code which contains =ar too many Ji=de=Bs =ormy taste. ?ow can preprocess the code to leave only oneconditional compilation set# without running it through thepreprocessor and e'panding all o= the JincludeBs and Jde=ineBsas well
-: There are programs =loating around called uni=de=# rmi=de=# and
7/25/2019 C faq programming
59/138
scpp which do e'actly this. Seequestion 10.1,.
15.12: ?ow can list all o= the preJde=ined identi=iers
-: ThereBs no standard way# although it is a common need. = thecompiler documentation is unhelp=ul# the most e'pedient way isprobably to e'tract printable strings =rom the compiler orpreprocessor e'ecutable with something like the $ni' stringsutility. 3eware that many traditional systemspeci=icpreJde=ined identi=iers
7/25/2019 C faq programming
60/138
-: See question 11.10.
15."&: ?ow can use a macro argument inside a string literal in themacro e'pansion
-: See question 11.10.
15."*: Bve got this tricky preprocessing want to do and canBt=igure out a way to do it.
-: Bs preprocessor is not intended as a generalpurpose tool. ;ather than =orcing it to do somethinginappropriate# consider writing your own little specialpurposepreprocessing tool# instead. You can easily get a utility like
make to run it =or you automatically.
= you are trying to preprocess something other than # considerusing a generalpurpose preprocessor.
7/25/2019 C faq programming
61/138
D%3$I
t is o=ten better to use a bona=ide =unction# which can take avariable number o= arguments in a wellde=ined way. Seequestions 1*.( and 1*.*.
Section 11. -+S6S7 Standard
11.1: Ghat is the A-+S StandardA
-: n 120 the -merican +ational Standards nstitute commissioned a committee# &[11# to standardi!e the language.-=ter a long# arduous process# including several widespreadpublic reviews# the committeeBs work was =inally rati=ied as -+S&.1*21202 on December 1(# 1202# and published in the spring o=
1225. 9or the most part# -+S standardi!es e'isting practice#with a =ew additions =rom and support =or multinational character sets . The -+S standard also=ormali!es the runtime library support routines.
/ore recently# the Standard has been adopted as an internationalstandard# S76% 2022:1225# and this S7 Standard replaces theearlier &.1*2 even within the $nited States. ts sections arenumbered di==erently
7/25/2019 C faq programming
62/138
11.": ?ow can get a copy o= the Standard
-: opies are available in the $nited States =rom
-merican +ational Standards nstitute11 G. ("nd St.# 1&th =loor+ew York# +Y 155&, $S- "1" ,(" (255
and
Ilobal %ngineering Documents1* nverness Gay %%nglewood# 7 0511" $S- &5& &2 "1*
0*( 12
n other countries# contact the appropriate national standardsbody# or S7 in Ieneva at:
S7 Salesase )ostale *,?1"11 Ieneve "5Swit!erland
.
-t the time o= this writing# the cost is ]1&5.55 =rom -+S or](15.55 =rom Ilobal. opies o= the original &.1*2 may still be available at ]"5*.55 =rom -+S or]1,".*5 =rom Ilobal. +ote that -+S derives revenues to supportits operations =rom the sale o= printed standards# so electroniccopies are not available.
n the $.S.# it may be possible to get a copy o= the original-+S &.1*2 as A9)S )$3 1,5A =rom
+ational Technical n=ormation Service $.S. Department o= ommerceSpring=ield# 4- ""1,15& (0 (,*5
The mistitled H-nnotated -+S StandardH# with annotations by?erbert Schildt# contains most o= the te't o= S7 2022C it is
7/25/2019 C faq programming
63/138
published by 7sborne6/cIraw?ill# S3+ 550012*"5# and sellsin the $.S. =or appro'imately ](5. t has been suggested thatthe price di==erential between this work and the o==icialstandard re=lects the value o= the annotations: they are plaguedby numerous errors and omissions# and a =ew pages o= the
Standard itsel= are missing. /any people on the net recommendignoring the annotations entirely. - review o= the annotations by live 9eather can be =ound on theweb at http:66www.lysator.liu.se6c6schildt.html .
The te't o= the ;ationale can beobtained by anonymous =tp =rom =tp.uu.net in directory doc6standards6ansi6&.1*21202# and is alsoavailable on the web athttp:66www.lysator.liu.se6c6rat6title.html . The ;ationale hasalso been printed by Silicon )ress# S3+ 52"2&5,5(.
11.&: /y -+S compiler complains about a mismatch when it sees
e'tern int =uncC
int =unc K ... L
or by changing the newstyle prototype declaration to match theoldstyle de=inition:
7/25/2019 C faq programming
64/138
e'tern int =uncC
t may also be sa=er to avoid AnarrowA =unction arguments and return types altogether.
See also question 1."*.
;e=erences: EF;1 Sec. -.1 p. 10,C EF;" Sec. -.&." p. "5"C -+SSec. &.&."."# Sec. &.*.(.&C S7 Sec. ,.&."."# Sec. ,.*.(.&C;ationale Sec. &.&."."# Sec. &.*.(.&C ?FS Sec. 2." pp. ",*#Sec. 2.( pp. ""&.
11.(: an you mi' oldstyle and newstyle =unction synta'
-: Doing so is per=ectly legal# as long as youBre care=ul . +ote however that oldstyle synta'is marked as obsolescent# so o==icial support =or it may beremoved some day.
;e=erences: -+S Sec. &..1# Sec. &.2.*C S7 Sec. ,..1#Sec. ,.2.*C ?FS Sec. 2."." pp. ",*# Sec. 2.".* pp. ",25.
11.*: Ghy does the declaration
e'tern =
7/25/2019 C faq programming
65/138
scope# so that all =ollowing declarations involving struct ' canat least be sure theyBre re=erring to the same struct '.
;e=erences: -+S Sec. &.1.".1# Sec. &.1.".,# Sec. &.*.".&C S7Sec. ,.1.".1# Sec. ,.1.".,# Sec. ,.*.".&.
11.0: donBt understand why canBt use const values in initiali!ersand array dimensions# as in
const int n Q *Cint aMnNC
-: The const quali=ier really means AreadonlyCA an obPect soquali=ied is a runtime obPect which cannot beassigned to. The value o= a constquali=ied obPect is there=orenot a constant e'pression in the =ull sense o= the term. Ghen you need a true compiletime constant# use a preprocessor Jde=ine.
;e=erences: -+S Sec. &.(C S7 Sec. ,.(C ?FS Secs. .11."#.11.&pp. "",.
11.2: GhatBs the di==erence between Aconst char pA andAchar const pA
-: Achar const pA declares a pointer to a constant character C Achar const pA declares aconstant pointer to a character .
;ead these Ainside outA to understand themC see also question1."1.
;e=erences: -+S Sec. &.*.(.1 e'amplesC S7 Sec. ,.*.(.1C;ationale Sec. &.*.(.1C ?FS Sec. (.(.( p. 01.
11.15: Ghy canBt pass a char to a =unction which e'pects aconst char
-: You can use a pointertoT where a pointertoconstT is e'pected. ?owever# the rule which permits slight mismatches in quali=ied pointer types isnot applied recursively# but only at the top level.
You must use e'plicit casts when assigning pointers which have quali=ier
7/25/2019 C faq programming
66/138
mismatches at other than the =irst level o= indirection.
;e=erences: -+S Sec. &.1.".,# Sec. &.&.1,.1# Sec. &.*.&C S7Sec. ,.1.".,# Sec. ,.&.1,.1# Sec. ,.*.&C ?FS Sec. .2.1 pp. ""1".
11.1": an declare main as void# to shut o== these annoying Amainreturns no valueA messages
-: +o. main must be declared as returning an int# and as takingeither !ero or two arguments# o= the appropriate types. =youBre calling e'it but still getting warnings# you may haveto insert a redundant return statement .
Declaring a =unction as void does not merely shut o== or
rearrange warnings: it may also result in a di==erent =unctioncall6return sequence# incompatible with what the caller e'pects.
;e=erences: -+S Sec. ".1.".".1# Sec. 9.*.1C S7 Sec. *.1.".".1#Sec. I.*.1C ?FS Sec. "5.1 p. (1,C TF) Sec. &.15 pp. *5*1.
11.1&: 3ut what about mainBs third argument# envp
-: tBs a nonstandard e'tension. = you reallyneed to access the environment in ways beyind what the standardgetenv =unction provides# though# the global variable environis probably a better avenue .
;e=erences: -+S Sec. 9.*.1C S7 Sec. I.*.1C ?FS Sec. "5.1 pp.(1,.
11.1(: believe that declaring void main canBt =ail# since Bmcalling e'it instead o= returning# and anyway my operatingsystem ignores a programBs e'it6return status.
-: t doesnBt matter whether main returns or not# or whether
7/25/2019 C faq programming
67/138
anyone looks at the statusC the problem is that when main ismisdeclared# its caller may not evenbe able to call it correctly
7/25/2019 C faq programming
68/138
Sec. ,.0.&."# Sec. ,.0.&.*.
11.10: Ghat does the message Awarning: macro replacement within astring literalA mean
-: Some pre-+S compilers6preprocessors interpreted macrode=initions like
Jde=ine T;-% print=
such that invocations like
T;-%C
were e'panded as
print=C
n other words# macro parameters were e'panded even insidestring literals and character constants.
/acro e'pansion is not de=ined in this way by EF; or byStandard . Ghen you do want to turn macro arguments intostrings# you can use the new J preprocessing operator# alongwith string literal concatenation :
Jde=ine T;-% Vprint=
See also question 11.1 above.
;e=erences: ?FS Sec. &.&.0 p. *1.
11.12: Bm getting strange synta' errors inside lines Bve Ji=de==edout.
-: $nder -+S # the te't inside a Aturned o==A Ji=# Ji=de=# orJi=nde= must still consist o= Avalid preprocessing tokens.AThis means that there must be no newlines inside quotes# and nounterminated comments or quotes . There=ore# naturallanguage comments andpseudocode should always be written between the Ao==icialAcomment delimiters 6 and 6.
7/25/2019 C faq programming
69/138
;e=erences: -+S Sec. ".1.1."# Sec. &.1C S7 Sec. *.1.1."#Sec. ,.1C ?FS Sec. &." p. (5.
11."5: Ghat are Jpragmas and what are they good =or
-: The Jpragma directive provides a single# wellde=ined AescapehatchA which can be used =or all sorts o= implementationspeci=ic controls and e'tensions: source listing control#structure packing# warning suppression # etc.
;e=erences: -+S Sec. &.0.,C S7 Sec. ,.0.,C ?FS Sec. &. p. ,1.
11."1: Ghat does AJpragma onceA mean =ound it in some header =iles.
-: t is an e'tension implemented by some preprocessors to help
make header =iles idempotentC it is essentially equivalent tothe Ji=nde= trick mentioned in question 15..
11."": s char aM&N Q AabcAC legal Ghat does it mean
-: t is legal in -+S #though use=ul only in rare circumstances. t declares an arrayo= si!e three# initiali!ed with the three characters BaB# BbB#and BcB# without the usual terminating BV5B character. Thearray is there=ore not a true string and cannot be used withstrcpy# print= Ws# etc.
/ost o= the time# you should let the compiler count theinitiali!ers when initiali!ing arrays .
;e=erences: -+S Sec. &.*.C S7 Sec. ,.*.C ?FS Sec. (.,.( p.20.
11."(: Ghy canBt per=orm arithmetic on a void pointer
-: The compiler doesnBt know the si!e o= the pointedto obPects.3e=ore per=orming arithmetic# convert the pointer either tochar or to the pointer type youBre trying to manipulate .
;e=erences: -+S Sec. &.1.".*# Sec. &.&.,C S7 Sec. ,.1.".*#Sec. ,.&.,C ?FS Sec. .,." p. "5(.
11."*: GhatBs the di==erence between memcpy and memmove
7/25/2019 C faq programming
70/138
-: memmove o==ers guaranteed behavior i= the source anddestination arguments overlap. memcpy makes no suchguarantee# and may there=ore be more e==iciently implementable.Ghen in doubt# itBs sa=er to use memmove.
;e=erences: EF;" Sec. 3& p. "*5C -+S Sec. (.11.".1#Sec. (.11."."C S7 Sec. .11.".1# Sec. .11."."C ;ationaleSec. (.11."C ?FS Sec. 1(.& pp. &(1"C )S Sec. 11 pp. 1,*,.
11.",: Ghat should malloc do ;eturn a null pointer or a pointer to5 bytes
-: The -+S6S7 Standard says that it may do eitherC the behavioris implementationde=ined .
;e=erences: -+S Sec. (.15.&C S7 Sec. .15.&C )S Sec. 1,.1 p.&0,.
11.": Ghy does the -+S Standard not guarantee more than si' caseinsensitive characters o= e'ternal identi=ier signi=icance
-: The problem is older linkers which are under the control o=neither the -+S6S7 Standard nor the compiler developers onthe systems which have them. The limitation is only thatidenti=iers be signi=icant in the =irst si' characters# notthat they be restricted to si' characters in length. Thislimitation is annoying# but certainly not unbearable# and ismarked in the Standard as Aobsolescent#A i.e. a =uture revisionwill likely rela' it.
This concession to current# restrictive linkers really had to bemade# no matter how vehemently some people oppose it. = youdisagree# or have thought o= a trick by which a compilerburdened with a restrictive linker could present the programmer with the appearance o= more signi=icance in e'ternalidenti=iers# read the e'cellentlyworded section &.1." in the&.1*2 ;ationale # which discusses severalsuch schemes and e'plains why they could not be mandated.
;e=erences: -+S Sec. &.1."# Sec. &.2.1C S7 Sec. ,.1."#Sec. ,.2.1C ;ationale Sec. &.1."C ?FS Sec. ".* pp. ""&.
11."2: /y compiler is rePecting the simplest possible test programs#with all kinds o= synta' errors.
7/25/2019 C faq programming
71/138
-: )erhaps it is a pre-+S compiler# unable to accept =unctionprototypes and the like.
See also questions 1.&1# 15.2# and 11.&5.
11.&5: Ghy are some -+S6S7 Standard library routines showing up asunde=ined# even though Bve got an -+S compiler
-: tBs possible to have a compiler available which accepts -+Ssynta'# but not to have -+Scompatible header =iles or runtimelibraries installed. Seealso questions 11."2# 1&."*# and 1&.",.
11.&1: Does anyone have a tool =or converting oldstyle programs to
-+S # or vice versa# or =or automatically generatingprototypes
-: Two programs# protoi!e and unprotoi!e# convert back and =orthbetween prototyped and Aold styleA =unction de=initions anddeclarations. These programs arepart o= the 9S9Bs I+$ compiler distributionC see question10.&.
The unproto program
7/25/2019 C faq programming
72/138
generating prototypes =or old =unctions with AnarrowAparametersC see question 11.&.>
9inally# are you sure you really need to convert lots o= oldcode to -+S The oldstyle =unction synta' is still
acceptable# and a hasty conversion can easily introduce bugs.
11.&": Ghy wonBt the 9robo!! /agic ompiler# which claims to be -+Scompliant# accept this code know that the code is -+S#because gcc accepts it.
-: /any compilers support a =ew nonStandard e'tensions# gcc moreso than most. -re you sure that the code being rePected doesnBtrely on such an e'tension t is usually a bad idea to per=orme'periments with a particular compiler to determine properties
o= a languageC the applicable standard may permit variations# orthe compiler may be wrong. See also question 11.&*.
11.&&: )eople seem to make a point o= distinguishing betweenimplementationde=ined# unspeci=ied# and unde=ined behavior.GhatBs the di==erence
-: 3rie=ly: implementationde=ined means that an implementationmust choose some behavior and document it. $nspeci=ied meansthat an implementation should choose some behavior# but need notdocument it. $nde=ined means that absolutely anything mighthappen. n no case does the Standard impose requirementsC inthe =irst two cases it occasionally suggests a small set o= likely behaviors.
+ote that since the Standard imposes no requirements on thebehavior o= a compiler =aced with an instance o= unde=inedbehavior# the compiler can do absolutely anything. nparticular# there is no guarantee that the rest o= the programwill per=orm normally. tBs perilous to think that you cantolerate unde=ined behavior in a programC see question &." =or arelatively simple e'ample.
= youBre interested in writing portable code# you can ignorethe distinctions# as youBll want to avoid code that depends onany o= the three behaviors.
See also questions &.2# and 11.&(.
;e=erences: -+S Sec. 1.,C S7 Sec. &.15# Sec. &.1,# Sec. &.1C
7/25/2019 C faq programming
73/138
;ationale Sec. 1.,.
11.&(: Bm appalled that the -+S Standard leaves so many issuesunde=ined. snBt a StandardBs whole Pob to standardi!e thesethings
-: t has always been a characteristic o= that certain constructsbehaved in whatever way a particular compiler or a particularpiece o= hardware chose to implement them. This deliberateimprecision o=ten allows compilers to generate more e==icientcode =or common cases# without having to burden all programswith e'tra code to assure wellde=ined behavior o= cases deemedto be less reasonable. There=ore# the Standard is simplycodi=ying e'isting practice.
- programming language standard can be thought o= as a treaty
between the language user and the compiler implementor. )artso= that treaty consist o= =eatures which the compilerimplementor agrees to provide# and which the user may assumewill be available. 7ther parts# however# consist o= rules whichthe user agrees to =ollow and which the implementor may assumewill be =ollowed. -s long as both sides uphold theirguarantees# programs have a =ighting chance o= workingcorrectly. = either side reneges on any o= its commitments#nothing is guaranteed to work.
See also question 11.&*.
;e=erences: ;ationale Sec. 1.1.
11.&*: )eople keep saying that the behavior o= i Q i is unde=ined#but Pust tried it on an -+Scon=orming compiler# and got theresults e'pected.
-: - compiler may do anything it likes when =aced with unde=inedbehavior # including doing what you e'pect. tBsunwise to depend on it# though. See also questions 11.&"#11.& and 11.&(.
Section 1". Stdio
1".1: GhatBs wrong with this code
char cC
7/25/2019 C faq programming
74/138
while ...
-: 9or one thing# the variable to hold getcharBs return valuemust be an int. getchar can return all possible charactervalues# as well as %79. 3y passing getcharBs return value
through a char# either a normal character might bemisinterpreted as %79# or the %79 might be altered and so never seen.
;e=erences: EF;1 Sec. 1.* p. 1(C EF;" Sec. 1.*.1 p. 1,C -+SSec. &.1.".*# Sec. (.2.1# Sec. (.2..*C S7 Sec. ,.1.".*#Sec. .2.1# Sec. .2..*C ?FS Sec. *.1.& p. 11,# Sec. 1*.1#Sec. 1*.,C TF) Sec. *.1 p. 5C )S Sec. 11 p. 1*.
1".": Ghy does the code
while K=getsC=putsC
L
copy the last line twice
-: n # %79 is only indicated a=ter an input routine has triedto read# and has reached endo==ile. $sually# you should Pust check thereturn value o= the input routine C o=ten#you donBt need to use =eo= at all.
;e=erences: EF;" Sec. ., p. 1,(C -+S Sec. (.2. Sec. (.2..1#Sec. (.2.15."C S7 Sec. .2. Sec. .2..1# Sec. .2.15."C ?FSSec. 1*.1( p. &0".
1".(: /y programBs prompts and intermediate output donBt always showup on the screen# especially when pipe the output throughanother program.
-: tBs best to use an e'plicit ==lush whenever outputshould de=initely be visible. Several mechanisms attempt toper=orm the ==lush =or you# at the Aright time#A but they tendto apply only when stdout is an interactive terminal.
;e=erences: -+S Sec. (.2.*."C S7 Sec. .2.*.".
1".*: ?ow can read one character at a time# without waiting =or the
7/25/2019 C faq programming
75/138
;%T$;+ key
-: See question 12.1.
1".,: ?ow can print a BWB character in a print= =ormat string
tried VW# but it didnBt work.
-: Simply double the percent sign: WW .
VW canBt work# because the backslash V is the compilerBsescape character# while here our problem is that the W isprint=Bs escape character.
See also question 12.1.
;e=erences: EF;1 Sec. .& p. 1(C EF;" Sec. ." p. 1*(C -+S
Sec. (.2.,.1C S7 Sec. .2.,.1.
1".2: Someone told me it was wrong to use Wl= with print=. ?ow canprint= use W= =or type double# i= scan= requires Wl=
-: tBs true that print=Bs W= speci=ier works with both =loat anddouble arguments. Due to the Ade=ault argument promotionsA# values o=type =loat are promoted to double# and print= there=ore seesonly doubles. See also questions 1".1& and 1*.".
;e=erences: EF;1 Sec. .& pp. 1(*(# Sec. .( pp. 1(*5C EF;"Sec. ." pp. 1*&((# Sec. .( pp. 1**2C -+S Sec. (.2.,.1#Sec. (.2.,."C S7 Sec. .2.,.1# Sec. .2.,."C ?FS Sec. 1*.0 pp.&*,(# Sec. 1*.11 pp. &,,0C TF) Sec. -.1 pp. 1"1&&.
1".15: ?ow can implement a variable =ield width with print= Thatis# instead o= W0d# want the width to be speci=ied at runtime.
-: print= will do Pust what you want. See alsoquestion 1".1*.
;e=erences: EF;1 Sec. .&C EF;" Sec. ."C -+S Sec. (.2.,.1C S7Sec. .2.,.1C ?FS Sec. 1*.11.,C TF) Sec. -.1.
1".11: ?ow can print numbers with commas separating the thousandsGhat about currency =ormatted numbers
7/25/2019 C faq programming
76/138
-: The routines in begin to provide some support =orthese operations# but there is no standard routine =or doingeither task.
;e=erences: -+S Sec. (.(C S7 Sec. .(C ?FS Sec. 11., pp. &51(.
1".1": Ghy doesnBt the call scan= work
-: The arguments you pass to scan= must always be pointers.To =i' the =ragment above# change it to scan= .
1".1&: Ghy doesnBt this code:
double dCscan=C
work
-: $nlike print=# scan= uses Wl= =or values o= type double# andW= =or =loat. See also question 1".2.
1".1*: ?ow can speci=y a variable width in a scan= =ormat string
-: You canBtC an asterisk in a scan= =ormat string means tosuppress assignment. You may be able to use -+S stringi!ingand string concatenation to accomplish about the same thing# orto construct a scan= =ormat string onthe=ly.
1".1: Ghen read numbers =rom the keyboard with scan= AWdVnA# itseems to hang until type one e'tra line o= input.
-: )erhaps surprisingly# Vn in a scan= =ormat string does notmean to e'pect a newline# but rather to read and discardcharacters as long as each is a whitespace character. See alsoquestion 1"."5.
;e=erences: EF;" Sec. 31.& pp. "(*,C -+S Sec. (.2.,."C S7Sec. .2.,."C ?FS Sec. 1*.0 pp. &*,(.
1".10: Bm reading a number with scan= Wd and then a string withgets# but the compiler seems to be skipping the call togetsR
-: scan= Wd wonBt consume a trailing newline. = the input numberis immediately =ollowed by a newline# that newline will
7/25/2019 C faq programming
77/138
immediately satis=y the gets.
-s a general rule# you shouldnBt try to interlace calls toscan= with calls to gets Cscan=Bs peculiar treatment o= newlines almost always leads to
trouble. %ither use scan= to read everything or nothing.
See also questions 1"."5 and 1"."&.
;e=erences: -+S Sec. (.2.,."C S7 Sec. .2.,."C ?FS Sec. 1*.0pp. &*,(.
1".12: =igured could use scan= more sa=ely i= checked itsreturn value to make sure that the user typed the numeric values e'pect# but sometimes it seems to go into an in=inite loop.
-: Ghen scan= is attempting to convert numbers# any
Top Related