-2

The standard defines array type meticulously, but I don't see any definition for array.

We might say "object of array type", however that can't be right as untyped objects (e.g. space allocated by malloc) is described as an array.


Motivation: The specification for %s in fprintf (C11 7.21.6.1/8) says:

the argument shall be a pointer to the initial element of an array of character type

but take the code char s[] = "hello"; printf("%s", s+1); then we passed a pointer to the second element. That definition appears to be assuming that array means any set of contiguous object(s).


Edit: seeing as I have picked up some "unclear what you're asking" votes, my question is: What is that definition of the term array as used by ISO/IEC 9899:2011 ?

M.M
  • 138,810
  • 21
  • 208
  • 365
  • The C FAQ is a useful resource: [So what is meant by the ``equivalence of pointers and arrays'' in C?](http://c-faq.com/aryptr/aryptrequiv.html) – Sinan Ünür May 30 '15 at 12:55
  • C++ has similar problems. For instance, it never says that an object is an array of characters; it only says that it is a "sequence of characters"... In C++ it's simply that nobody has gone back and fine-combed the core standardese. It's full of ambiguities like that. I imagine C is in a similar position. Do feel free to open an issue, ideally with wording. (That said, I think C is frozen, it won't receive any future standard releases.) – Kerrek SB May 30 '15 at 12:59
  • @KerrekSB sounds like a nightmare :) – M.M May 30 '15 at 13:02
  • Well I don't see how your example `printf("%s", s+1);` is in conflict with "*the argument shall be a pointer to the initial element of an array of character type*". A C-string is clearly defined as an array of characters terminated by `\0`. Just because you specify another initial element by adding `+1` does not change that or anything else. – Stefan Falk May 30 '15 at 13:04
  • @MattMcNabb: Well... nowadays there's a careful process where every tiny paper receives tons of attention, but imagine back when the entire thing was standardized: Who would do a *careful review* of 600 pages of core wording? In fact, just recently there was a [fix in the iostreams wording](https://github.com/cplusplus/draft/commit/f48861115c9f191d0a7b51e73092c07eeb431399) that meant that nobody had ever done a careful word-by-word review of that. It happens. Usually "we all know what it should mean", and that's it. – Kerrek SB May 30 '15 at 13:05
  • @KerrekSB I wouldn't have said that a subset of an array was also an array (until now, perhaps) – M.M May 30 '15 at 13:08
  • @StefanFalk `s+1` points to the second element of the object of array type `s`, not the initial element ; and `s+1` is not the initial element of an object of array type – M.M May 30 '15 at 13:10
  • It is not the initial element of `s` but it is *an* initial element as seen from `printf()`. you pass an "*n-minus-one*" sized sub array of `s` to that function. Where is the problem? It still follows the convention: Give a valid address to a `\0` terminated char array. – Stefan Falk May 30 '15 at 13:18
  • @StefanFalk is there an object of array type whose address is `s+1` ? – M.M May 30 '15 at 13:22
  • It seems like you need to take the rules for pointer arithmetic and subobjects, shake a bit, and then dub the result "array" for convenience and you can make sense of this. Note that we're *not* saying "must be a pointer to the first subobject of an object of array type". – Kerrek SB May 30 '15 at 13:24
  • @KerrekSB so you'd go with something that involves any contiguous non-empty subset of an array also being an array? (on a bit of a tangent here, but we're OK with `char r[8]; char (*pr)[6] = (char(*)[6])(r+1);` ?) – M.M May 30 '15 at 13:35
  • I don't understand what you mean by the question "*if there is an object of array type whose address is* `s+1`". Why would that be necessary? Why doesn't it bother you that they don't state that the char array has to be zero-terminated but the fact that you can pass a sub-array does? Why do you want the array that starts from `s+1` to `strlen(s)-1` to be an object by itself. What makes you think that is necessary? – Stefan Falk May 30 '15 at 13:39
  • @MattMcNabb: Well, I know what is *meant*: That the pointer is obtained by pointer arithmetic on pointers to the subobjects of an object of array type. I don't know if there's normative wording for this concept, but I know what is meant by the concept, if that makes sense. I don't want "sub-arrays" to be objects in their own right, i.e. I don't think the cast `int(*)[10]` to `int(*)[9]` should be valid. – Kerrek SB May 30 '15 at 13:39
  • For what it's worth, if you're familiar with `std::vector` in C++ -- is that class UB? Who said that `data()[1]` is valid? (That is actually unclear at the moment. Nobody really knows whether calling the allocator "creates" an object in a suitable way. Individual elements exist, but does there exist any ambient array? If not, how can you do pointer arithmetic? We just all know that it *should* work.) – Kerrek SB May 30 '15 at 13:41
  • @StefanFalk Because 7.21.6.1/8 says that it has to be the first element of an array. – M.M May 30 '15 at 13:46
  • I don't share your concerns about the null termination. The standard says that "characters are written until the null", and you can combine that with the rules on the validity of pointer arithmetic to draw your own conclusions. – Kerrek SB May 30 '15 at 13:48
  • @KerrekSB I think if `s+1` is meant to be pointing to a "subarray" then it should be legal to describe that subarray via an array type as in those casts – M.M May 30 '15 at 14:02
  • 1
    For "be a pointer to the initial element of an array..." to work, "array" must be any finite sequentially accessible objects of a given type. This implies at last 2 reqs: For the given type, the array has correct alignment. - not an issue with `char` and address of all the array elements is good (e.g. can't go past the end of memory or segment). Good question, but @Matt, unfortunately appears to be a [I don't get no respect!](http://en.wikipedia.org/wiki/Rodney_Dangerfield) one. – chux - Reinstate Monica May 30 '15 at 21:15
  • @chux yeah... 9 downvotes with no explanation , must be close to a badge of some sort :) – M.M May 30 '15 at 23:20
  • Can any of the close-voters please explain what is unclear about the question? – M.M May 31 '15 at 23:17

1 Answers1

0

Arrays are defined in the C Standard, 6.2.5, paragraph 20:

An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type. Array types are characterized by their element type and by the number of elements in the array. An array type is said to be derived from its element type, and if its element type is T, the array type is sometimes called ‘‘array of T’’. The construction of an array type from an element type is called ‘‘array type derivation’’.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • 1
    That's the definition of *array type*, not *array* . – M.M May 30 '15 at 13:06
  • @Drop There are arrays which are not of array type though (e.g. the space allocated by `malloc`). To put it another way, all objects of array type are obviously arrays, but there are also other arrays. – M.M May 30 '15 at 13:11
  • Please explain how any "array" can **not** be of "array type". – Andrew Henle May 30 '15 at 13:12
  • 1
    @AndrewHenle the space allocated by malloc has no type, but it is usually considered to be an array – M.M May 30 '15 at 13:17
  • Also the space pointed to by `s+1` in my other example doesn't have any declared type (e.g. `*(s+1)` is not an array type) – M.M May 30 '15 at 13:20
  • @MattMcNabb - Because `malloc()` must return a pointer "suitably aligned so that it may be assigned to a pointer to any type of object" - including a pointer to an **array**. And you're blatantly **wrong** in your "(s+1)" example. If "s" is an array of N elements, (s+1) is an array of (N-1) elements. – Andrew Henle May 30 '15 at 13:23
  • @Drop I don't know, that's why I asked this question. However if you do not consider it an array then you would have to conclude that `char *a = malloc(1); a[0] = '\0'; printf("%s\n", a);` causes undefined behaviour (because of the standard quote in my question). – M.M May 30 '15 at 13:28
  • @AndrewHenle I'm not claiming anything about the `s+1` example so i'm not sure how I can be wrong about it ... This question is asking how *array* is defined and the `s+1` example is provided as something that it has to be consistent with (or perhaps we could consider that the text in 7.21.6.1/8 is defective, as an alternative solution) – M.M May 30 '15 at 13:30