Path: ...!weretis.net!feeder9.news.weretis.net!news.quux.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: question about linker Date: Thu, 28 Nov 2024 11:58:36 -0800 Organization: None to speak of Lines: 78 Message-ID: <87frnbt9jn.fsf@nosuchdomain.example.com> References: <87plmfu2ub.fsf@nosuchdomain.example.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Thu, 28 Nov 2024 20:58:41 +0100 (CET) Injection-Info: dont-email.me; posting-host="5d82f7250b92e1d8e1e5ba7e656a3e2b"; logging-data="730062"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/DcknMska104y8+7IyS3em" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:SYwEmZjsFGM7V+zFZ8Aib7/nRjM= sha1:25YVG2/hf/4h1AV7XvbrJE/2RXU= Bytes: 3867 Bart writes: [...] > I think 'const' is confusing for similar reasons that VLAs can be both > confusing and awkward to implement. > > That's because both really apply to /types/, not directly to variables. Sure. For example, given const int n = 42; n is of type `const int`, and &n is of type `consts int*`. Of course that implies that n itself is const. I'm not sure what's so confusing about that. If const applied *directly* to variables, it's hard to see how something like &n could be treated consistently. "const" has to apply to types anyway. Are you suggesting that it should have an additional meaning when applied to variables? What would be the advantage of that? > So both const and a VLA can specified deep inside a type-spec, where > there may be no storage allocated, inside a cast for example, but > here's a simpler one: > > int n; > const int (*A)[n]; > > This declares a pointer to a VLA, so no storage is allocated for the > VLA. (I'm not even sure how you'd allocate it in the program, given > that VLAs normally go on the stack.) It declares *and defines* (allocates storage for) a pointer to a VLA. You could allocate the array any way you like. For example: int n = 42; const int (*A)[n]; const int vla[n]; A = &vla; (Though it's hard to see how you'd initialize the elements of `vla`.) > And the 'const' applies to the array elements, which here don't > exist. Right, just as in const int *ptr; the const applies to an int object which doesn't yet exist. > To make the pointer itself const, then 'const' needs to be at > the top-level, which bizarrely needs to go not only in the middle, but > /after/ the pointer which is to be const: > > const int (*const A)[n]; Yes, C's declaration syntax can be confusing. I almost certainly wouldn't have done it that way if I were designing the language from scratch. But it's unambiguous, it's not going to change, and complaining about it does no good. (Have you ever considered trying to help people understand it?) The issue you mention isn't directly related to "const"; it applies equally to all type qualifiers (const, restrict, volatile, _Atomic). cdecl is a good tool for unravelling complex declarations. It doesn't handle VLAs, but there are workarounds for that : $ cdecl Type `help' or `?' for help cdecl> explain const int (*A)[n] syntax error cdecl> explain const int (*A)[42] declare A as pointer to array 42 of const int So A is a pointer to array n of const int. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com void Void(void) { Void(); } /* The recursive call of the void */