2

I was wondering: is string defined as a keyword or typedef name in any plain C (not C++) implementation?

Meaning: either the implementation has a string keyword, or it has a built-in header with a line similar to:

typedef char* string;

Eärendil Baggins
  • 552
  • 1
  • 8
  • 23
  • 2
    CS50 has a `string` type, which is a `typedef` for `char *`. – mch Sep 17 '18 at 07:48
  • 4
    Possible duplicate of [Does C have a string type?](https://stackoverflow.com/questions/14709323/does-c-have-a-string-type) – Bagus Tesa Sep 17 '18 at 07:48
  • oh indeed [CS50 have a kind of string](https://cs50.stackexchange.com/questions/9183/string-variable-is-not-working). but that being said, it uses `char*` behind the scene.. seems my knowledge is outdated. – Bagus Tesa Sep 17 '18 at 07:49
  • 2
    Of course, C++ implementations cannot define a `string` keyword because the standard library already uses `string` as a `typedef` name. – melpomene Sep 17 '18 at 08:16
  • 3
    CS50 isn't a C _implementation_, by the formal meaning of the C standard, where an implementation = a compiler. It's merely a crap library used to teach students how to become bad C programmers. – Lundin Sep 17 '18 at 11:40
  • After the edit, the question is no longer off-topic. Voting to re-open. – Lundin Sep 17 '18 at 11:42
  • Just to address the parenthetic aside: No C++ implementation can introduce a *keyword* spelt `string`, either. (Note that `std::string` is a library type, not a keyword). – Toby Speight Sep 17 '18 at 17:05
  • What do you mean by "built-in header"? – melpomene Sep 17 '18 at 19:20
  • stuff like `windows.h`, which is not in the C standard but you have in a certain compiler's implementation. If they have a technical name I'll edit the question with that. – Eärendil Baggins Sep 17 '18 at 19:21

3 Answers3

5

No C standard has string as a keyword. The idea that some folk have of writing

typedef char* string;

is to be reprehended, as it obfuscates.

Use a char*, const char*, char[] or const char[] as appropriate, to model a NUL-termimated string of characters. There are other ways of modelling text, but this one is the one used by the C standard library.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • I know very well how text is treated in C, and having worked with some folks who `typedef` a `string` type as `char*` I also agree with your statement. However, mine was more of a general curiosity. Since some C implementations have an integrated boolean type which is basically writing `typedef int boolean`, `typedef 0 false` and `typedef 1 true` I was wondering if the same was done by someone for the strings. – Eärendil Baggins Sep 17 '18 at 19:05
  • I actually agree with your contention that `typedef`ing `char*` to `string` is unnecesary (since there's no real simplification or abstraction involved), I'm just not to sure of your stated reason of obfuscation. It seems to me that you could easily use that same arguments for `typedef struct {double numerator; double denominator;} rational` rather than just a tageed struct everywhere. – paxdiablo Sep 18 '18 at 06:42
  • @pawxdiablo I find the string typedef particularly objectionable as it buries a pointer. Indeed you can do the same with struct but to newcomers and tired maintainers of c code a string can almost pass as having automatic storage duration. So it seems to cause more problems than it solves. – Bathsheba Sep 18 '18 at 06:50
  • I once tried porting a C graphics library, oriented for beginners similar to the Borland Graphics Interface and the Python Turtle, to C++. To make it supposedly more "beginner-friendly", they did `typedef char* string;` and used `string myFunction() {...}` EVERYWHERE in their code, which drove me nuts, as I wanted to fix the entire library to not have any naming conflicts with anything in the C++ `std` namespace. They even typedef'd FILE* as stream and int as bool. You can see this abomination here: https://github.com/fffelix-jan/LibgraphicsExperiments/blob/main/libgraphics/genlib.h – Felix An Sep 30 '22 at 15:13
5

Some implementations may provide a string but they would be doing so against the express wishes of the ISO standard, and you could argue that they are therefore not a C implementation. That's because, in C11 7.31 Future library directions, it explicitly states:

Function names that begin with str, mem, or wcs and a lowercase letter may be added to the declarations in the <string.h> header.

Earlier, in 7.1.3 Reserved Identifiers, we see (my emphasis):

All identifiers with external linkage in any of the following sub-clauses (including the future library directions) and errno are always reserved for use as identifiers with external linkage

So implementations should not be doing this. Of course, you're free to create something called string in your own code, you just have to be aware of the issues. If you value portability, you should not be defining anything that meets this criteria. Otherwise, a future C standard may render your code non-compilable.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
4

No, C implementations do not provide a string keyword and they can't, really. As C99 says (4. Conformance):

  1. [...] A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program.3)

3) This implies that a conforming implementation reserves no identifiers other than those explicitly reserved in this International Standard.

The keywords defined by C99 are exactly:

auto       enum        restrict    unsigned   
break      extern      return      void
case       float       short       volatile
char       for         signed      while
const      goto        sizeof      _Bool
continue   if          static      _Complex
default    inline      struct      _Imaginary
do         int         switch
double     long        typedef
else       register    union

string is not on that list.

Later on the standard defines which identifiers are reserved for use by the implementation:

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
  • All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

If an implementation wants to provide an additional keyword, it would have to be something like __string or _String.

Under 7.26 Future library directions it says:

7.26.11 String handling <string.h>

  1. Function names that begin with str, mem, or wcs and a lowercase letter may be added to the declarations in the <string.h> header.

So the "best" an implementation can do is to define string as a function, and only if <string.h> is included.

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • If what you say about keywords is true, why can some implementations of C (Microsoft comes to mind) define bool types when bool is not on that list? I'm confused. – Eärendil Baggins Sep 17 '18 at 19:10
  • @EärendilBaggins Can't reproduce. Which version of MSVC are you using? – melpomene Sep 17 '18 at 19:11
  • last time I did it it was the one included in Visual Studio 2017. The Windows C type for that is called `BOOL`. More info on that here: https://stackoverflow.com/questions/830067/when-should-bool-and-bool-be-used-in-c – Eärendil Baggins Sep 17 '18 at 19:13
  • @EärendilBaggins `BOOL` is not a keyword or built into the compiler. It's [a typedef in a Windows header](https://blogs.msdn.microsoft.com/oldnewthing/20041222-00/?p=36923/). – melpomene Sep 17 '18 at 19:17
  • I edited the question to be clearer. I meant both keyword and typedefs in built-in headers, since those are where the implementations have more freedom. It makes sense anyway now that I understand the difference with a keyword. – Eärendil Baggins Sep 17 '18 at 19:20