Path: csiph.com!weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Effect of CPP tags Date: Sat, 06 Jan 2024 19:28:27 -0800 Organization: None to speak of Lines: 135 Message-ID: <874jfpstyc.fsf@nosuchdomain.example.com> References: <%cFlN.140487$xHn7.115393@fx14.iad> <87jzomrvh8.fsf@nosuchdomain.example.com> <878r52rljn.fsf@nosuchdomain.example.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Info: dont-email.me; posting-host="d0ba5c5ff5439800f0d0915b07472ef5"; logging-data="1019223"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/cz7iZuATzwKfG/47rkvDW" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:misyO1AOGjhSsIjoJavVmnN4mi4= sha1:biFCGbtp5k1p9gKX9ceVnxsMxa8= Xref: csiph.com comp.lang.c:379905 Bart writes: > On 07/01/2024 01:15, Keith Thompson wrote: >> Bart writes: >>> On 06/01/2024 21:40, Keith Thompson wrote: >>>> Bart writes: >>>> [...] >>>>> The concept is not that easy to get your head around either, the idea >>>>> that the variable aspects of a VLA are associated with its type, not >>>>> its value or instance. >>>> Oh? I don't find it difficult at all. It's the kind of thing you >>>> learn >>>> once, and then you know it. Now you know it, but you're still >>>> complaining for some reason. >>> >>> Maybe you've never had to implement it. It is certainly not intuitive: >> No, I haven't. I worked on compilers in the distant past (for Ada, >> which doesn't distinguish on the language level between array with >> constant and non-constant bounds), but I haven't implemented VLAs for C. >> We were talking about the fact that, as you say, "variable aspects >> of a >> VLA are associated with its type, not its value or instance". Are you >> saying that makes implementing it unreasonably difficult? > > It makes it bizarre. It would make a typedef involving a VLA type > something to be executed at runtime; it is executable code. Sure. A VLA type specifier like `int[n]` or `int[rand()%10+1]` involves evaluating the (non-constant) expression that specifies the length. Of course that requires executable code, whether it's part of a typedef or part of an object definition. I don't understand why you find that bizarre. >>> int n=rand(); >>> >>> typedef int T[n]; // here the size is stored with the type >> Yes, of course it is. And keep in mind that typedef doesn't create >> a >> new type. A compiler will create, at compile time, some internal node >> (or whatever data structure it uses) representing the anonymous type >> `int[n]`, and will associate an implicitly created automatic object with >> it to hold its length or size. It will then create a node representing >> the typedef T, referring to the anonymous array type. >> >>> int A[n]; // here you'd expect it with each variable >> Why would you expect that? > > Why would expect it to be part of some anonymous, associated type? > > If you had a counted string type, would you expect its length to be > part of the data belonging to the object, and or part of a separate > type object? If a language considers "array of 10 ints" and "array of 20 ints" to be the same type, I suppose I'd expect the length information to be associated with an object. The type would just be "array of int". If they're different types, as they are in C, I'd expect that information to be associated with the type. If I have 123 objects of type "array of 10 ints", there's no reason for the compiler to store the value 10 123 times in its internal symbol table. And if I have: int n = 10; typedef int vla[10]; vla twod_array[123]; then there's no need to store the value 10 separately for each of the 123 elements of `twod_array`. > You might call it metadata, but being a type doesn't come to > mind. What would be the point of that; what could you do with that > type? You could define objects of the type, you could apply sizeof to it, you could define a type that points to it, or that's an array of it. You know, all the stuff you can normally do with a type. > Suppose you had a counted string variable S, currently set to "ABC" so > that its length (which you say is naturally part its type) is 3. What exactly do you mean by a "counted string variable"? If you mean you have a variable whose current value is "ABC", and you can update it so its value becomes "ABCDEF", then of course the count has to be associated with the object. But a VLA object's size is fixed at run time when it's created. > Assume you could somehow do this: > > typeof(S) T > > would you expect T to also have a length 3? What would the string contain? Without knowing what the type is *in C terms*, I can't answer that. > It doesn't make sense. But you say that's how VLAs work: > > int A[rand()]; > > typeof(A) B; > > B has the same length as A, whatever that is. Well, C doesn't have typeof, but you can certainly do something similar. (I'm changing the length expression because rand() can return 0, which would cause undefined behavior.) typedef int rvla[rand() % 10 + 1]; rvla A; rvla B; A and B are of the same type and therefore have the same length. The obvious way to implement that would be to store the length in an anonymous object associated with the type. You're saying you'd expect the size be associated with A and with B, not with the type. Given: int row_count = 1000; int col_count = 2000; int vla_2d[row_count][col_count]; you have 1000 rows of 2000 elements each. Would you expect to create 1000 implicit objects, one for each row, each holding the value 2000? Since the standard specifies the behavior of VLAs, not how they're implemented, a conforming compiler could do that, but why would you expect it? [...] -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Medtronic void Void(void) { Void(); } /* The recursive call of the void */