Path: csiph.com!weretis.net!feeder6.news.weretis.net!feeder7.news.weretis.net!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c++ Subject: Re: [QT creator on "nix"] - getting a strict 8 bit (1 byte) array with no padding Date: Sat, 23 Nov 2019 17:06:47 -0800 Organization: None to speak of Lines: 154 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="e0930e6abf7d5b15723004258724c134"; logging-data="22601"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18YazQcdCU5OrdrLOyGvelT" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:yr0tfTdn/hsMEHlgg1cu+rtApeQ= sha1:HZNMRqARz2W+odTRaoPqacsEj44= Xref: csiph.com comp.lang.c++:70026 Soviet_Mario writes: > On 23/11/2019 21:27, Keith Thompson wrote: >> Soviet_Mario writes: >>> Il 23/11/19 07:04, Keith Thompson ha scritto: >>>> Soviet_Mario writes: >>>> [...] >>>>> let's say it explicitely >>>>> >>>>> if I have >>>>> union >>>>> { >>>>> struct >>>>> { >>>>> u_int_8 Red, Green, Blue, Alpha; >>>>> }; >>>>> u_int_32 AllChannels; >>>>> }; >>>>> >>>>> without PRAGMA, do I have any explicit or implicit warranty >>>>> that my union be 32 bit long ? If so, PRAGMA is useless. If >>>>> not, it seems it might be useful. >>>> >>>> Fixing the spelling of uintN_t (n=8,32) and adding a tag to the union so >>>> you can use it to define objects: >>> >>> again ... >>> Keith, I did not edit the header manually, and sized ints >>> HERE are spelled as I wrote. >> [SNIP] >>> as you can see the types are spelled as I wrote them, and a >>> search for uintXX_t does not find anything >> >> I didn't know where the names u_int_8 and u_int_32 came from, >> and assumed they were misspellings of uint8_t and uint32_t. >> >> On my own system, #include introduces the non-standard >> type names u_int{8,32}_t. It doesn't introduce u_int_{8,32}, and I >> don't see that name in the code you quoted (other than in your union >> definition) or anywhere under /usr/include on my system. > > yes I miss-spelled forgetting the final _t (but the pieces > of headers pasted mentioned it) To be very clear, if you need an unsigned integer type of at least 8 bits, there is almost no good reason not to use uint8_t. There is no good reason to use some system-specific (or even undocumented) equivalent. "Almost" means you might have to consider older implementations that don't support / . Any version of g++ you're likely to encounter should support C++11 or later -- older versions might require an explicit option. Even older versions are likely to support or as an extension. >> On the other hand, the types uint8_t and uint32_t are defined by the C >> and C++ standards (starting with C99 and C++11, respectively). >> >> Nobody is suggesting that you're lying or manually editing headers. All >> we're saying is that uint8_t and uint32_t are the *standard* types that >> meet your requirements, and there is no good reason to use non-standard >> types with similar names. >> >> Do you have some reason to prefer to use u_int_8 rather than uint8_t? > > no no reason at all. I just noticed this subtle difference > after having rewritten always :) > But It will take short to do a mass-replace and change the > included header > >> >>> is this that big problem ? >>> I guess the variations stands for the same concept >> >> Yes. Names other than uint8_t are non-standard and will cause your code >> not to compile in many environments. > > > well I must have mis-expressed again when I said I was > looking for a portable way, I actually meant I needed a way > that allowed proper data exchange from front-end gambas side > and C++ engine. > > I'll never deploy the program anywhere else. So as long as > it compiles here, fine enough If you use uint8_t it will compile. >> >> >>>> union u { >>>> struct { >>>> uint8_t Red, Green, Blue, Alpha; >>>> }; >>>> uint32_t AllChannels; >>>> }; >>>> >>>> (You have an anonymous struct, which is standard but wasn't added until >>>> C11, so older compilers might not support it, or might not support it >>>> by default.) >>> >>> it gives me warnings indeed, but seems to compile nevertheless >> >> What warnings? > > that anonymous structs (or unions) are non standard and > supported only with GCC later than some version. It's always better to copy-and-paste diagnostic messages rather than trying to summarize them. BTW, I made a serious mistake here. C supports anonymous structs as of C11. C++ does not support them at all. g++ does support them as an extension. With "g++ -std=c17 -pedantic", I get "warning: ISO C++ prohibits anonymous structs [-Wpedantic]". My apologies for that. If you're only using gcc, you can use anonymous structs in C++, but your code will be non-portable. [...] >>>> There is *no* guarantee about which of the four uint8_t members >>>> correspond to which part of AllChannels. >>> >>> and I don't need such warranty : I use AllChannels only for >>> mass-copying, assignments, copy constructor. When I need >>> access to separate channels I use named members. >> >> What operations do you need on AllChannels that you can't perforom on >> the struct? You can assign structs. > > uhm ... memberwise or all-at-once ? > I thought struct assignment (normally I wrote operator =) > should pass through memberwise copying. > So the aim was to copy everything in one assignment only > instead of four of them. > But if struct can be assigned smartly enough then the union > is not needed. The semantics of struct assignment (assuming you haven't overloaded operator=) are equivalent to the semantics of copying memberwise, but in the case of a struct containing 4 uint8_t members, no sane compiler will do anything other than a 32-bit copy. That's assuming the struct has an alignment that permits a 32-bit copy. If copying the entire structure is the only operation you care about, keep it simple: just define the structure and use ordinary structure assignment. [...] -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */