Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Sort char array Date: Sat, 12 Oct 2019 11:55:47 -0700 Organization: None to speak of Lines: 87 Message-ID: References: <20191007174244.385138503569a8bc6d4eec9d@g{oogle}mail.com> <20191008022725.36fbd95aa45ba185290e5e11@gmail.com> <1q_mF.841756$Zy3.585129@fx33.am4> <20191009020207.b533aa1c6d95f44eb314ffc1@gmail.com> <5alnF.1041354$WI2.353384@fx34.am4> <20191010003208.ff29e87d2de1e17c50f96c74@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="e7dcfb9e050a69901d7f41fe98f66f92"; logging-data="8664"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18Xzj9kpJu2trDJ5pOfViWy" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:mTxOHRc6MNlr2YGqSNioyfbbhMU= sha1:G6l/wQAKDzB5qDKYVqLsiHNzCyE= Xref: csiph.com comp.lang.c:146898 David Brown writes: > On 11/10/2019 20:34, Keith Thompson wrote: >> David Brown writes: >> [...] >>> But people often have to combine code from different places - and then >>> you get challenges. It's (relatively) easy to keep your own code >>> consistent, or code developed within the one team. But if you make use >>> of third-party code that generates an array of "long long int" and >>> returns a pointer to long long, and another piece of code needs an array >>> of int64_t via a pointer to int64_t, what do you do? You know your code >>> will not be used on systems that have "long long int" that is not >>> identical in size and representation to "int64_t", and have static >>> assertions enforcing that. >>> >>> How do you pass the data pointers safely (and efficiently)? >> >> By casting the pointers, I suppose. The behavior is not absolutely >> guaranteed, but it's unlikely to cause problems. > > In that case, you are relying on the same semantics that I am suggesting > could be guaranteed. Except that I would use a pointer cast, which is a large red flag that this code can break if some assumptions (which I would document in comments) are violated. > You agree that it is likely (but not guaranteed) > that code that mixes these pointers will work as expected. Given that the corresponding types have the same representation, yes. I would be very careful about making that assumption. > You agree > that it is likely to be the only sensible way to code certain > situations. Um, what? No, I didn't say that. All I did was mention the first solution that sprang to mind. I didn't spend a lot of time exploring alternatives. > You agree that even though the types are the same sizes and > representations (if they were not, compatibility would be out of the > question) there is no guarantee that the code will work - you need to > confirm it for each specific case unless your compiler provides > additional guarantees (like gcc's "-fno-strict-aliasing" flag, or > "may_alias" attributes). > > My suggestion is that this /could/ be guaranteed in the standard. And the cost would be that code that *unnecessarily* assumes, for example, that long and long long are compatible would compile without errors under implementations where that assumption happens to be true, and fail to compile when ported to a system where they aren't. It would be a new way of planting time bombs in your code. I understand that you think the benefits would make it worthwhile. I just disagree. The ideal solution would be to use the same times in the first place, but the existence of two or more libraries makes that impractical in some cases. > An alternative, with which I would be equally (or more) happy, would be > that there be no compatibility between any of the different integer > types (i.e., types like "int32_t", "size_t", "int", "long", etc., would > be incompatible in all cases) - but that there be a way to convert > pointer types safely. That is to say, you could explicitly tell the > compiler "I have a pointer to type T. Make a pointer to type U with the > same address, which I can access safely". Such a feature could have > many benefits, especially if you didn't have to stick to types of the > same size (you could make your own "malloc", for instance). You want this to work for pointers to types of different sizes? I don't see how you could safely convert a uint16_t* to uint32_t*, for example. > What I don't like at the moment is that there is occasional need for > converting pointers that are not compatible, and that the only sensible > way to do it is not guaranteed to work. > >> But I wouldn't assume (without very good reason) that my code will >> *never* be used on systems where this would break -- thus the static >> assertions (which I would have mentioned if you hadn't already). -- Keith Thompson (The_Other_Keith) kst-u@mib.org Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */