Embedded Systems October 2000 Vol13_11

Issue link:

Contents of this Issue


Page 77 of 181

PROGRAMMING POINTERS machine tha t uses the ASCII character set, this would display 'a' as 97_ C++ changed the type of characte r lite rals to char, so that: ostream &operatorĀ« (ostream &, char); would be the be tte r match for the call. This assures that overloaded ope rators such as Ā« have the expected behavior. Bjam e StroustnlP, the inve nto r of C++, obsel-ved that: "Surprisingly, giving 'a' type char in C++ doesn 't cause compa tibili ty problems. Except fOl- the pa tho logical example si zeof(' a'), every construct that can be expressed in both C and C++ gives the arne result."2 In C++, si zeof(' a') yie lds th e same result a sizeof(char), which is always I. In C, si zeof(' a') yie lds the same result as sizeof(int), which may be 1, but is much mo re likely to be 2 or 4. String literals in C As 1 explained a few months ago, a rrays in C and C++ al-e not just point- ers.3 Although C and C++ have a stan- dard conversio n from "array of T" to "pointe r to T" which often makes arrays appear to be pointers, arrays really are a rrays no ne theless. In C, a string Literal such as "abcd" has type "array of char." Since "abcd" consists of five characters- ' a " 'b' , 'c' , 'd' , and '\0' (the null characte r)-its precise type is "array of 5 char." In any event, almost eve ry time you use a string Literal in an expression, the compiler u-eats it as if it we re a "pointer to char". Why isn 't the type of a string literal "array of const char'? After all, programs shouldn't be overwliting the values of their suing literals, should they? A C compile r fo r embedded sys- tems may place string lite rals into ROM. In tha t case, a program that attempts to write over a string lite ral will be trying to wlite into ROM. ot good. Even in systems that don' t have pro- grammable ROM, C programs that oven vrite string lite rals produce dire resul ts. A C compile r is allowed to "pool" string lite rals. That is, a compil- e r can treat two or more string lite rals with the same value as if they a re all the same object and allocate just one copy. If one pa rt of a program ove rwTites the value of a string lite ral I-esidin in RAM, it may affect the value of the lit- e ral as seen elsewhere in the program. For example, suppose your pro- gram contai ns a fun ction: void rotate_Left(char *); which rota tes a null-termina ted cha r- acte r a rray left by one characte r. For example: char digits[] = "9867530"; rotate_Left(digits); leaves the value "8675309" in array digits. Now suppose the program contains the call: rotate_Left ("He L Lo"); which changes the value o f the string lite ral "HeL Lo" to "eLLoH". If the com- pile r is pooling lite rals, then the call: pri ntf( "HeLLo") ; elsewhe re in the program migh t print "eL LoH." This is almost certainly not the correct o utput. It seems tha t the simplest way to prevent such mishaps would be for C to give string lite rals type "array of const char. " T hen, the compil e r would rej ect a call such as: rotate_Left( "He L Lo"); for attempting an invalid pointer conver- sion. The compile r would transform "HeLLo" [rom "array of const char" to "pointe r to const char". Function rot a t e_ L eft expects a parame ter of type "pointer to (non-const) char," but 76 oaOBER 2000 Embedded Systems Programming there's no slL'1ndard conversion from "poin ter to const char" to "pointe r to (non-const) char." The compiler will issue a diagnostic message at this point. So, why d oesn ' t C treat string lit- e l-a ls as "a rray o f const char"? Because C didn ' t acquire the const qualifie r until the language was in to its second decade. By the n, too much code had been written tha t treated string li teral as arrays of no n-const char. T he C standards committee decided tha t the standard should sanc- tion existing code rathe r than force programme rs to rewrite it. Even though string lite rals have type "ar ray of char" in C, a program that attempts to modify a slling Ijteral has undefined behavior. That is, attempting to modify a string Ijteral is an error, but compilers are not obljgated to detect it. String literals in C++ For compatibility with C, string lite ral in C++ originally had type "a rray of char." T his allowed C code to be recompiled as C++ without change, but it produced surpl-ising behavio r during fun ctio n ove rload resolution. As I explained last year, a C++ pro- gram can overload functio ns whose pa rame te r types diffe r only in their use of the const qualifie r." For exam- pl e, a program can provide two dis- tinct fun ctio ns named f decla red as: void f(char *); void f(char const *); Because string lite rals are supposed to be non-modifiable, you might rea- sona bly expect a call such as f("abc") to call f(char const *). In the past, it didn 't. Rathe r, it called f(char *) because "abc" had type "array of (non- const) char. " A few years ago, th e standards com- mittee opted to change C++ so that string lite rals have type "array of const char." According to the C++ standa rd, f("abc") should call f(char const *). Many, but no t all , C++ compile rs have since adopted this change.

Articles in this issue

Archives of this issue

view archives of EETimes - Embedded Systems October 2000 Vol13_11