Deutsch English Français Italiano |
<vt5n0s$inuo$1@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: David Brown <david.brown@hesbynett.no> Newsgroups: comp.lang.c Subject: Re: do { quit; } else { } Date: Wed, 9 Apr 2025 13:51:55 +0200 Organization: A noiseless patient Spider Lines: 132 Message-ID: <vt5n0s$inuo$1@dont-email.me> References: <vspbjh$8dvd$1@dont-email.me> <8634enhcui.fsf@linuxsc.com> <vsph6b$ce6m$5@dont-email.me> <86ldsdfocs.fsf@linuxsc.com> <20250406161323.00005809@yahoo.com> <86ecy5fjin.fsf@linuxsc.com> <20250406190321.000001dc@yahoo.com> <86plhodtsw.fsf@linuxsc.com> <20250407210248.00006457@yahoo.com> <vt15lq$bjs0$3@dont-email.me> <vt2lp6$1qtjd$1@dont-email.me> <vt31m5$2513i$1@dont-email.me> <vt3d4g$2djqe$1@dont-email.me> <vt3iqh$2ka99$1@dont-email.me> <868qoaeezc.fsf@linuxsc.com> <vt3oeo$2oq3p$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Wed, 09 Apr 2025 13:51:58 +0200 (CEST) Injection-Info: dont-email.me; posting-host="39048323a720df50869558e92437b3ec"; logging-data="614360"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/3Asm/8NKv8maD+YocebYoFph78eqiAas=" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 Cancel-Lock: sha1:ndVj+xL2cFfMZsEu4uptYB7860M= In-Reply-To: <vt3oeo$2oq3p$1@dont-email.me> Content-Language: en-GB Bytes: 5035 On 08/04/2025 20:04, bart wrote: > On 08/04/2025 18:32, Tim Rentsch wrote: >> bart <bc@freeuk.com> writes: >> >>> On 08/04/2025 15:50, David Brown wrote: >>> >>>> On 08/04/2025 13:35, bart wrote: >>>> >>>>> But this need not be the case. For example this is module A: >>>>> >>>>> -------------------------- >>>>> #include <stdio.h> >>>>> >>>>> typedef struct point {float a; float b;} Point; >>>>> >>>>> float dist(Point); >>>>> >>>>> int main(void) { >>>>> Point p = {3, 4}; >>>>> printf("%f\n", dist(p)); >>>>> } >>>>> -------------------------- >>>>> >>>>> And this is module B that defines 'dist': >>>>> >>>>> >>>>> -------------------------- >>>>> #include <math.h> >>>>> >>>>> typedef float length; >>>>> typedef struct _tag {length x, y;} vector; >>>>> >>>>> length dist(vector p) {return sqrt(p.x*p.x + p.y*p.y);} >>>>> -------------------------- >>>>> >>>>> The types involved are somewhat different, but are compatible >>>>> enough for it to work. >>>> >>>> The two types are entirely compatible. >>> >>> Are they? >> >> No, they are not. The type names 'Point' and 'vector' name two >> distinct types, and those types are not compatible, because >> the two struct tags are different. >> >> Because the two types are not compatible, even just calling the >> function dist() is undefined behavior. > > I get an incompatible error (from the example you snipped) even when I > remove both struct tags. Of course. They are different types. > > I can't use the same struct tag in the same scope as one will clash with > the other. Yes. > But if I have the second in an inner scope, then I again get > the error. Yes. > > It doesn't seem to be anything to do with struct tags. Correct. Every time you declare a struct - when you have "struct {" or "struct X {", you declare a /new/ type that is incompatible with any other type (except for inter-translation unit compatibility). > > Two typedefs for same struct layout appear to create distinct types; > this fails: "typedef" does not create types - it merely creates an alias for an existing type. (Is it a questionable choice of keyword? Yes, it certainly is. So you have to learn what it means.) "struct" declarations (and "union" declarations) create types. > > typedef struct {float x, y;} Point; This creates a new anonymous type, then declares "Point" to be an alias for it. > typedef struct {float x, y;} vector; This creates a new anonymous type, then declares "vector" to be an alias for it. "Point" and "vector" thus refer to different types. > > Point p; > vector v; > > p=v; > > > But this works: > > typedef struct {float x, y;} Point, vector; This creates a new anonymous type, then declares "Point" and "vector" to be aliases of it. They therefore refer to the same type. > > Point p; > vector v; > > p=v; > > So it seems to depend on whether Point and vector share the same > internal descriptor for the struct. > It depends on whether they are declared as aliases for the same type, or for different types. > In my original example, the structs were defined in separate translation > unit, so the compiler has to take things on trust. > Yes - as explained in 6.2.7p1 of the standard. Having them in separate translation units is critical to the difference.