Novice question using MPLABx + XC8 If i define my_variable using; #define my_variable 0b10000000 And then I use it in a function that expects a 'char'; void my_function(char i); I get a compiler warning; warning: (752) conversion to shorter data type By changing the function prototype to expect an 'int' the warning goes away so I think the defined my_variable is being assigned as an 'int' So my question is how or can I structure my define so the defined my_variable is assigned as a 'char'.. I cannot see anything useful in the mplabx documentation. Thanks.
XC8 novice question
Started by ●September 11, 2016
Reply by ●September 11, 20162016-09-11
On 9/11/2016 12:02 AM, rwood wrote:> Novice question using MPLABx + XC8 > > If i define my_variable using; > > #define my_variable 0b10000000 > > And then I use it in a function that expects a 'char'; > > void my_function(char i); > > > > I get a compiler warning; > > warning: (752) conversion to shorter data type > > By changing the function prototype to expect an 'int' the warning goes away so > I think the defined my_variable is being assigned as an 'int' > > So my question is how or can I structure my define so the defined my_variable > is assigned as a 'char'.. > > I cannot see anything useful in the mplabx documentation.Why not explicitly cast the value to a "char" in the define-ition (*if* you expect to always use it as such)? Note that you should decide if you do/don't care about signedness of the value (i.e., is this value 128 or -127?) as "char" can vary from implementation to implementation.
Reply by ●September 11, 20162016-09-11
On 11-Sep-16 5:55 PM, Don Y wrote:> On 9/11/2016 12:02 AM, rwood wrote: >> Novice question using MPLABx + XC8 >> >> If i define my_variable using; >> >> #define my_variable 0b10000000 >> >> And then I use it in a function that expects a 'char'; >> >> void my_function(char i); >> >> >> >> I get a compiler warning; >> >> warning: (752) conversion to shorter data type >> >> By changing the function prototype to expect an 'int' the warning goes >> away so >> I think the defined my_variable is being assigned as an 'int' >> >> So my question is how or can I structure my define so the defined >> my_variable >> is assigned as a 'char'.. >> >> I cannot see anything useful in the mplabx documentation. > > Why not explicitly cast the value to a "char" in the define-ition > (*if* you expect to always use it as such)? > > Note that you should decide if you do/don't care about signedness > of the value (i.e., is this value 128 or -127?) as "char" can vary > from implementation to implementation.Hi Don, I tried using: #define my_variable (char)0b10000000 and also: #define my_variable ((char)0b10000000) Both of which compile without issue but still the warning about converting to a shorter data type persists. Thanks.
Reply by ●September 11, 20162016-09-11
On Sun, 11 Sep 2016 02:55:23 -0700, Don Y <blockedofcourse@foo.invalid> wrote:>On 9/11/2016 12:02 AM, rwood wrote: >> Novice question using MPLABx + XC8 >> >> If i define my_variable using; >> >> #define my_variable 0b10000000 >> >> And then I use it in a function that expects a 'char'; >> >> void my_function(char i); >> >> >> >> I get a compiler warning; >> >> warning: (752) conversion to shorter data type >> >> By changing the function prototype to expect an 'int' the warning goes away so >> I think the defined my_variable is being assigned as an 'int' >> >> So my question is how or can I structure my define so the defined my_variable >> is assigned as a 'char'.. >> >> I cannot see anything useful in the mplabx documentation. > >Why not explicitly cast the value to a "char" in the define-ition >(*if* you expect to always use it as such)? > >Note that you should decide if you do/don't care about signedness >of the value (i.e., is this value 128 or -127?) as "char" can vary >from implementation to implementation.Are there still some idiotic systems that are defining char as _signed_ ???? If we really have to use such outdated systems, why aren't we using 6 bit characters with all upper case (or all lower case) ? In fact why not use 5 bit Baudot as in Manchester computers ?
Reply by ●September 11, 20162016-09-11
On 11/09/16 12:56, upsidedown@downunder.com wrote:> On Sun, 11 Sep 2016 02:55:23 -0700, Don Y > <blockedofcourse@foo.invalid> wrote: > >> On 9/11/2016 12:02 AM, rwood wrote: >>> Novice question using MPLABx + XC8 >>> >>> If i define my_variable using; >>> >>> #define my_variable 0b10000000 >>> >>> And then I use it in a function that expects a 'char'; >>> >>> void my_function(char i); >>> >>> >>> >>> I get a compiler warning; >>> >>> warning: (752) conversion to shorter data type >>> >>> By changing the function prototype to expect an 'int' the warning goes away so >>> I think the defined my_variable is being assigned as an 'int' >>> >>> So my question is how or can I structure my define so the defined my_variable >>> is assigned as a 'char'.. >>> >>> I cannot see anything useful in the mplabx documentation. >> >> Why not explicitly cast the value to a "char" in the define-ition >> (*if* you expect to always use it as such)? >> >> Note that you should decide if you do/don't care about signedness >> of the value (i.e., is this value 128 or -127?) as "char" can vary >>from implementation to implementation. > > > Are there still some idiotic systems that are defining char as > _signed_ ???? > > If we really have to use such outdated systems, why aren't we using 6 > bit characters with all upper case (or all lower case) ? In fact why > not use 5 bit Baudot as in Manchester computers ? >Yes, there are "idiotic" systems that have signed plain char. Most older, bigger systems (x86, PPC, MIPS, etc.) seem to have char signed by default. The way to handle it is to only ever use "char" when you really mean a simple ASCII character. For anything else, use "uint8_t" or "int8_t" as appropriate. If you have a weird fascination for meaningless names, you can also use "unsigned char" or "signed char". But every time I see a function that takes a "char" and is not either a legacy C library function, or clearly looking for an ASCII character with a name like "debugPrintChar()", I know the code is bad.
Reply by ●September 11, 20162016-09-11
On 11/09/16 12:25, rwood wrote:> On 11-Sep-16 5:55 PM, Don Y wrote: >> On 9/11/2016 12:02 AM, rwood wrote: >>> Novice question using MPLABx + XC8 >>> >>> If i define my_variable using; >>> >>> #define my_variable 0b10000000 >>> >>> And then I use it in a function that expects a 'char'; >>> >>> void my_function(char i); >>> >>> >>> >>> I get a compiler warning; >>> >>> warning: (752) conversion to shorter data type >>> >>> By changing the function prototype to expect an 'int' the warning goes >>> away so >>> I think the defined my_variable is being assigned as an 'int' >>> >>> So my question is how or can I structure my define so the defined >>> my_variable >>> is assigned as a 'char'.. >>> >>> I cannot see anything useful in the mplabx documentation. >> >> Why not explicitly cast the value to a "char" in the define-ition >> (*if* you expect to always use it as such)? >> >> Note that you should decide if you do/don't care about signedness >> of the value (i.e., is this value 128 or -127?) as "char" can vary >> from implementation to implementation. > > > Hi Don, I tried using: > > #define my_variable (char)0b10000000 > > and also: > > #define my_variable ((char)0b10000000) > > > Both of which compile without issue but still the warning about > converting to a shorter data type persists. > > Thanks. >I suspect that on your system, "char" is signed by default. When you write a number like 0b10000000, it is an "int" (unless it is outside the range of "int", in which case it gets bumped up to the first match of unsigned int, long int, unsigned long int, long long int, unsigned long long int). By casting it to "char", you are asking the compiler to fit the value 128 into a type with a range -128 to 127 (assuming I am right that char is signed on your system). That is causing the warning. Never use "char" for numbers. It is /always/ the wrong type - its signedness will vary from system to system, and the name does not match the usage. And if your code might be used on other systems, remember that on some DSPs "char" is not 8 bits. Use "uint8_t" or "int8_t" as appropriate for numbers (or "uint_least8_t" and "int_least8_t" for very portable code). So: #define my_variable ((uint8_t) 0b10000000) void my_function(uint8_t i); Also consider: static const uint8_t my_variable = 0b10000000; instead of the #define, unless you really need it to be a #define'd value (such as to give the size of an array, or because you have a crap compiler).
Reply by ●September 11, 20162016-09-11
Am 11.09.2016 um 12:56 schrieb upsidedown@downunder.com:> On Sun, 11 Sep 2016 02:55:23 -0700, Don Y > <blockedofcourse@foo.invalid> wrote:> Are there still some idiotic systems that are defining char as > _signed_ ????Given that such systems are explicitly allowed by the C standard, there's nothing particularly idiotic about them. But are there still idiotic programmers who use plain "char" in situations where they care about signedness? Well, yes, there are. Which is why coding standards such as MISRA forbid using plain char.> If we really have to use such outdated systems, why aren't we using 6 > bit characters with all upper case (or all lower case) ? In fact why > not use 5 bit Baudot as in Manchester computers ?For starters: because those _are_ forbidden under the rules of the language. Anyway, making plain char unsigned does not really solve any problem, so IMHO it's by no means idiotic to keep it signed. It may appear to provide a solution to the issue: "How to keep non-ASCII characters in a plain char?" Except that it does so very incompletely, at best, because there are way more non-ASCII characters than an 8 bits unsigned char can possibly hold. If one designed a new language like C today, 'char' would probably be called 'byte', or it would be emitted in favour of {u,}int8_t, whereas char would be 16 or 32 bits wide, and character and string constants UTF-8. But that's 20/20 hind sight, 30 years after the fact.
Reply by ●September 11, 20162016-09-11
Am 11.09.2016 um 09:02 schrieb rwood:> If i define my_variable using; > > #define my_variable 0b10000000That's a blatant misnomer, because that's not at all a variable. It's a constant-valued macro. The distinction is important, so maybe you should go back to your training materials to learn more.> I get a compiler warning; > > warning: (752) conversion to shorter data typeOf course you do. Another subject to look up in the books: what is the type of an integer constant? You'll have to check the compiler manual here, too, because that's non-standard syntax in your constant.> By changing the function prototype to expect an 'int' the warning goes > away so I think the defined my_variable is being assigned as an 'int'It's not assigned at all. Please learn about the difference between the preprocessor and the compiler proper.
Reply by ●September 11, 20162016-09-11
On Sun, 11 Sep 2016 13:36:59 +0200, Hans-Bernhard Br�ker <HBBroeker@t-online.de> wrote:>Am 11.09.2016 um 12:56 schrieb upsidedown@downunder.com: >> On Sun, 11 Sep 2016 02:55:23 -0700, Don Y >> <blockedofcourse@foo.invalid> wrote: > >> Are there still some idiotic systems that are defining char as >> _signed_ ???? > >Given that such systems are explicitly allowed by the C standard, >there's nothing particularly idiotic about them. > >But are there still idiotic programmers who use plain "char" in >situations where they care about signedness? Well, yes, there are. >Which is why coding standards such as MISRA forbid using plain char. > >> If we really have to use such outdated systems, why aren't we using 6 >> bit characters with all upper case (or all lower case) ? In fact why >> not use 5 bit Baudot as in Manchester computers ? > >For starters: because those _are_ forbidden under the rules of the language. > >Anyway, making plain char unsigned does not really solve any problem, so >IMHO it's by no means idiotic to keep it signed.While this have been true for more than 30 years ago when everything was 7 bit ASCII or at least ISO646, Of course EBCDIC had also some extended ranges. Later on, VT220 multinational and later on Latin1 character sets utilized the while 8 bit range as a single _unsigned_ linear range.>It may appear to provide a solution to the issue: "How to keep non-ASCII >characters in a plain char?"Unsigned char was the answer for at least 5-10 years before UCS2.>Except that it does so very incompletely, >at best, because there are way more non-ASCII characters than an 8 bits >unsigned char can possibly hold.That is true. For correctly storing Unicode characters, a 21 bit data type is required. There are some more or less workarounds for storing these Unicode characters, such as UTF-8 (1-3 bytes), UTF-16 (2-4 bytes) or as I once suggested UTF-64 on the Unicode list (three 21 bit characters in a 64 bit computer word e.g. Itanium.>If one designed a new language like C today, 'char' would probably be >called 'byte', or it would be emitted in favour of {u,}int8_t,that would be OK. {u,}int8_t, please.>whereas >char would be 16 or 32 bits wide,actually 21 bit values.>and character and string constants >UTF-8.UTF-8 is a quite reasonable compromize for most lnguages.>But that's 20/20 hind sight, 30 years after the fact.Having done IT applications for more than 30 years, the problem was well known in those days. The video (dot matrix) display units of those days were not capable of displaying very good glyphs, but still good for Latin, Cyrillic or Arabic glyphs, but ware quite bad on Est-Asian glyphs.
Reply by ●September 11, 20162016-09-11
On 9/11/2016 3:25 AM, rwood wrote:> On 11-Sep-16 5:55 PM, Don Y wrote: >> On 9/11/2016 12:02 AM, rwood wrote: >>> Novice question using MPLABx + XC8 >>> >>> If i define my_variable using; >>> >>> #define my_variable 0b10000000 >>> >>> And then I use it in a function that expects a 'char'; >>> >>> void my_function(char i); >>> >>> >>> >>> I get a compiler warning; >>> >>> warning: (752) conversion to shorter data type >>> >>> By changing the function prototype to expect an 'int' the warning goes >>> away so >>> I think the defined my_variable is being assigned as an 'int' >>> >>> So my question is how or can I structure my define so the defined >>> my_variable >>> is assigned as a 'char'.. >>> >>> I cannot see anything useful in the mplabx documentation. >> >> Why not explicitly cast the value to a "char" in the define-ition >> (*if* you expect to always use it as such)? >> >> Note that you should decide if you do/don't care about signedness >> of the value (i.e., is this value 128 or -127?) as "char" can varyGrrrr.... s/-127/-128/ (Moral: don't mix physical activities with mental ones! :<)>> from implementation to implementation. > > Hi Don, I tried using: > #define my_variable (char)0b10000000 > and also: > #define my_variable ((char)0b10000000) > > Both of which compile without issue but still the warning about converting to > a shorter data type persists.Would you expect no warnings on: signed short int my_counter = 32768; (i.e., to use your notation: 0b1000 0000 0000 0000)? Hint: signed shorts are effectively [-32768,32767]. Any time the compiler has latitude to "make up its own mind" about something, you should DEPRIVE it of that latitude! If you expect something to never be negative, then declare it as unsigned (there are some issues on some platforms where you can incur a small performance penalty but, chances are, YOU aren't going to be dealing with those). Otherwise, DECLARE it to be signed -- as a reminder that it's range of values includes negative ones (at the expense of some POSITIVE ones!) [Elsewhere (this newsgroup?) we discussed using TFTP as a file transfer protocol. It uses a 16 bit "block counter" in the protocol. There are implementations that have defined it as "short int" -- or just "short". See the problem? It's a *counter* so it's always intended to have positive values (you can't have "negative items") so never exceeds 32767! The next value in the "count sequence" is -32768!] Imagine you'd written my example above as: #define ITERATIONS (32768) ... signed short int my_counter = ITERATIONS; wouldn't you *want* the compiler to let you know that "it can't count that high" (with a signed short)? Or, more indirectly: counter_t my_counter = ITERATIONS; [imagine someone changes the declaration for counter_t and/or ITERATIONS] That's why you should treat warnings as errors -- not errors in the code, per se, but, rather, errors in your thinking and expectations! (the code will almost always *run* -- but not the way you had *hoped* it would run!) As you tweak the syntax to make the error go away, you should be asking yourself, "why do I *have* to do this? What is the compiler trying to DISCOURAGE me from doing??" (HInt: chances are, it is SMARTER than you!) Kinda like looking down the barrel of a gun and your friend saying, "Are you SURE you want to be doing that?? (with one in the chamber)" As an exercise, you should also play with: (signed) <value> (char) (unsigned) <value> (unsigned char) <value> etc. with differing (signed and unsigned) <value>s and notice how the compiler treats each variant.