EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

XC8 novice question

Started by rwood September 11, 2016
On 9/11/2016 4:35 AM, David Brown wrote:
> 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).
A drawback to this approach is it allows the OP to continue to think of it as a "variable". Either rename it ("my_constant" or "MY_CONSTANT") or use a manifest constant so each reference is ACTUALLY replaced with the PREPROCESSOR SUBSTITUTION: MY_CONSTANT = 7; (wrong!) becomes: 128 = 7; (which is CLEARLY wrong!) [Time for bed...]
On 9/11/2016 3:56 AM, 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_ ????
Apparently so! Regardless (always worth a chuckle to say "irregardless"!), it's a latitude that the compiler has been afforded. You don't want the compiler to make *any* decisions for you regarding the suitability of a particular value (in an assignment, calculation, etc.).
> 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 ?
TDD's and Telex still use 5b codes (well, I dunno if Telex is still around; it's been 30+ years since I worked with it... or TWX for that matter!). [N.B. converting between it and USASCII isn't a "linear mathematical transform"; a lookup table is almost the only effective approach (coupled with a "FIGS/LTRS" state bit). By contrast, USASCII <-> EBCDIC is far more easier to "mathematically transform". Gray codes, OTOH, convert easier one way than the other!]
On 9/11/2016 6:14 AM, upsidedown@downunder.com wrote:
> 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.
Not a problem with a PDS-1 (mid 70's vintage) -- *if* you could afford one! :>
On 11/09/16 16:32, Don Y wrote:
> On 9/11/2016 4:35 AM, David Brown wrote: >> 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). > > A drawback to this approach is it allows the OP to continue to think > of it as a "variable". Either rename it ("my_constant" or "MY_CONSTANT") > or use a manifest constant so each reference is ACTUALLY replaced with > the PREPROCESSOR SUBSTITUTION: > MY_CONSTANT = 7; (wrong!) > becomes: > 128 = 7; > (which is CLEARLY wrong!) > > [Time for bed...] > >
Well, clearly he needs to pick a better name for his "variable". I don't know if he just picked a bad name, or if he is confused about variables and constants. But if "my_variable" is declared as a "const", then writing "my_variable = 7" will give a compile-time error just as surely as it would with a pre-processor symbol.
On 11/09/16 15:32, Don Y wrote:
> On 9/11/2016 4:35 AM, David Brown wrote: >> 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). > > A drawback to this approach is it allows the OP to continue to think > of it as a "variable". Either rename it ("my_constant" or "MY_CONSTANT") > or use a manifest constant so each reference is ACTUALLY replaced with > the PREPROCESSOR SUBSTITUTION: > MY_CONSTANT = 7; (wrong!) > becomes: > 128 = 7; > (which is CLEARLY wrong!) > > [Time for bed...]
Except, of course, that 0b10000000 == 512, which is probably the source of the original "warning: (752) conversion to shorter data type" Everybody should occasionally re-read the "Frequently Questioned Answers" http://yosefk.com/c++fqa/
On 11/09/16 17:13, Tom Gardner wrote:
> On 11/09/16 15:32, Don Y wrote: >> On 9/11/2016 4:35 AM, David Brown wrote: >>> 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). >> >> A drawback to this approach is it allows the OP to continue to think >> of it as a "variable". Either rename it ("my_constant" or "MY_CONSTANT") >> or use a manifest constant so each reference is ACTUALLY replaced with >> the PREPROCESSOR SUBSTITUTION: >> MY_CONSTANT = 7; (wrong!) >> becomes: >> 128 = 7; >> (which is CLEARLY wrong!) >> >> [Time for bed...] > > Except, of course, that 0b10000000 == 512, which is probably the > source of the original "warning: (752) conversion to shorter > data type"
Oops. Please ignore my dyslexia, or maybe my eyesight is going.
> Everybody should occasionally re-read the "Frequently Questioned > Answers" http://yosefk.com/c++fqa/
On 9/11/2016 7:58 AM, David Brown wrote:
> Well, clearly he needs to pick a better name for his "variable". I don't know > if he just picked a bad name, or if he is confused about variables and constants. > > But if "my_variable" is declared as a "const", then writing "my_variable = 7" > will give a compile-time error just as surely as it would with a pre-processor > symbol.
Yes, but IME much easier to see whay you've done wrong (looking at the cpp(1) output). Similar to writing: if (4 == count)... instead of: if (count == 4)...
On Sun, 11 Sep 2016 15:02:48 +0800, 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.
I assume this is C11 we're talking about, or some vendor-specific C. At any rate, a #define is a preprocessor operation that just does a text substitution. So as far as the compiler itself is concerned, you didn't call my_function(my_variable); you called my_function(0b10000000); Since literal numerical constants default to type 'int' in C, this means that the compiler "sees" an int with a value that _just happens_ to be small enough to fit into a character. Two good ways to get around this are to define my_variable as a const (really, it should be "my_constant"), or to use a cast: static const char my_variable = 0b10000000; OR #define my_variable ((char)(0b10000000)) A halfway decent compiler will see the "static const" business and, unless you take the address of "my_variable" will just quietly turn it into a constant in the background, and optimize out actually putting it somewhere in memory. -- Tim Wescott Control systems, embedded software and circuit design I'm looking for work! See my website if you're interested http://www.wescottdesign.com
On 11/09/16 22:15, Don Y wrote:
> On 9/11/2016 7:58 AM, David Brown wrote: >> Well, clearly he needs to pick a better name for his "variable". I >> don't know >> if he just picked a bad name, or if he is confused about variables and >> constants. >> >> But if "my_variable" is declared as a "const", then writing >> "my_variable = 7" >> will give a compile-time error just as surely as it would with a >> pre-processor >> symbol. > > Yes, but IME much easier to see whay you've done wrong (looking at the > cpp(1) output). > > Similar to writing: > if (4 == count)... > instead of: > if (count == 4)...
Well, there may be differences of opinion here - and certainly experience and preferences are personal, making it hard to say "you are wrong". But you are wrong. Writing "if (4 == count)" is wrong. The last thing you need in your code is to write it backwards - it messes with your thinking, your writing, your reading and your understanding. There are only three reasons why you would want to write "if (4 == count)". Either /all/ of these are true: 1. You have trouble writing correct C code, even with the basic stuff (noting that everyone starts out as a beginner). 2. You have a very poor quality compiler that can't check for such mistakes. 3. You can afford to make mistakes and produce broken code, but can't afford software such as PC-Lint (or just gcc) to check such mistakes. 4. You have no code reviews or other code quality control. 5. You don't test your code, so don't see the consequences of the mistake. /or/ You are required to program to a coding standard designed by numpties who make the assumptions above (i.e., MISRA - a mixture of good but mostly obvious ideas and a selection of downright bad ideas left over from the 90's). /or/ You are small and green, and rely on the force. And when 900 years old /you/ are, speak normally /you/ will not. No one looks at the C pre-processor output. There is no advantage in an error that could be found by look at it. If you declare your constant values as "const", then the compiler will stop with an error if you try to assign to them after initialisation. The error will be in the obvious place, and will be clear - you don't get better than that.
On 11/09/16 18:19, Tom Gardner wrote:
> On 11/09/16 17:13, Tom Gardner wrote: >> On 11/09/16 15:32, Don Y wrote: >>> On 9/11/2016 4:35 AM, David Brown wrote: >>>> 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). >>> >>> A drawback to this approach is it allows the OP to continue to think >>> of it as a "variable". Either rename it ("my_constant" or >>> "MY_CONSTANT") >>> or use a manifest constant so each reference is ACTUALLY replaced with >>> the PREPROCESSOR SUBSTITUTION: >>> MY_CONSTANT = 7; (wrong!) >>> becomes: >>> 128 = 7; >>> (which is CLEARLY wrong!) >>> >>> [Time for bed...] >> >> Except, of course, that 0b10000000 == 512, which is probably the >> source of the original "warning: (752) conversion to shorter >> data type" > > Oops. Please ignore my dyslexia, or maybe my eyesight is going. >
Actually, you raise a good point - 0b10000000 is hard to read. 0b constants are fine for small values, and okay for bigger values if there are plenty of 0's and 1's. But your eyes need a transition every 4 or 5 digits for clock recovery. So numbers like this are often better expressed as hex (0x80), or with shifts (1u << 7) or perhaps (0b1000 << 4), if that suits a pattern with other defined constants in the code. Or use C++14, and write 0b1000'0000. (The ' separator the C++ standards folks picked may not be the nicest choice, but it is better than nothing.)

The 2024 Embedded Online Conference