3

There are no answers to this on the internet that I could find, and I've looked twice over the last 4 months.

In MPLab v8.88 using the Hi-Tech ANSI C Compiler, I have this line of code:

const   uint8 SUM_THRESHOLD_MIN = 15;   /* comment edited out   */

and I get the warning:

Warning [364] C:\*directory edited out* \ *filename_edited_out*.c; 273.35 attempt to modify object qualifed const

(excuse the edits, but I felt I should edit out personal yet superfluous details).

It is not my code, and I'd just use a #define, but others want to use a const (for those that don't know: using a const guarantees a proper typecast of a value, and can save you from some weird issues related to typecasting and data types; it's not my favorite way of doing it, but it's not a bad idea either).

There are several const initializations happening in the same block of code, and they all give me this warning. They are in a .c file, in a void function. I have other files with void functions where I initialize const uint8's and there are no warnings in those files. I searched globally, and found no other instance of the variable except where it gets used in the void function (so there aren't any issues with redefining or anything like that). To be clear, these const's are not part of any structure or anything strange, they are just declared in the void function in the .c file.

I have uint8 properly typedef'd, and not #define'd (see comments).

Can someone help me get rid of this warning?

EDIT: If I paste one of the const uint8's into another .c file directly after a const uint16 that doesn't throw the error, like this:

const uint16 rate_bias_time_constant[NUM_RATE_CHANNELS][RATE_BIAS_STEP_MAX] = 
    {30,120,480,960,  300,120,180,240,  300,120,180,240 }; // comment edited out
const   uint8 SUM_THRESHOLD_MIN = 15;   /* comment edited out   */

I get warning 364 in this file for this const uint8 but not for the const uint16. If I change SUM_THRESHOLD_MIN from a uint8 to a uint16, I still get the warning. For completeness, if I change it from all uppercase to all lower case, I still get the warning. If I change the line to, e.g.:

const uint8 SUM_THRESHOLD_MIN[2] = {15,2};  /* comment edited out   */

There is no warning.

Butzke
  • 1,012
  • 12
  • 27
Bob
  • 848
  • 2
  • 9
  • 21
  • Is `uint8` a proper `typedef` or just a `#define`? – Dave Tweed Sep 24 '13 at 19:30
  • The code says: "typedef unsigned char uint8;" and in a different file there are const int16's and uint8's initialized the same way with no warnings. – Bob Sep 24 '13 at 19:34
  • Is that piece of code in a header (.h) file which maybe is included multiple times in a .c file? – m.Alin Sep 24 '13 at 19:52
  • Is the line of code inside a function or outside of a function? – Joe Hass Sep 24 '13 at 19:56
  • The piece of code that throws the warning is in a .c file. All of the uint8 (there are 8 warnings) and a single int16 const declarations in this file throw this warning, but there is a const char and a const unsigned int that don't throw the warning in this .c file, and there are const uint8 declarations in other files that aren't throwing warnings. – Bob Sep 24 '13 at 20:01
  • @Joe Hass, it is in a void function, and the const uint8's in other files are also in void functions – Bob Sep 24 '13 at 20:03
  • Can you provide some info about the "block of code" where these errors occur? – user28910 Sep 24 '13 at 20:15
  • 1
    You should provide more info (the whole .c module) if you want good answers. – m.Alin Sep 24 '13 at 20:28
  • By any chance, do the other files have embedded compiler directives (e.g., `#pragma`s) that turn off that particular warning? – Dave Tweed Sep 24 '13 at 21:36
  • @m.Alin: I'm afraid I can't release the whole file to the public (company code), but I will try my best to answer questions that will help figure this out. – Bob Sep 25 '13 at 11:57
  • @Dave Tweed: There are no #pragma's to shut off warnings in the other files. I'm probably the first person to even care that there are warnings that compiled this code. I considered using a suppress warnings pragma, but the other files in this project aren't giving me problems... – Bob Sep 25 '13 at 11:57
  • @user28910: it's in a .c file, after the #includes, after the local prototypes, in the third function of the file, a void function, and the const's causing the trouble are in the middle of the declaration of the rest of the local variables in this void function. The int16 const that throws the warning is in the same function, locally declared after an "if". There is a const unsigned int and a const char that don't throw the warnings in this same file, and other files have const uint8's and don't throw the warning. – Bob Sep 25 '13 at 12:00
  • How are you building the project -- are you compiling files from the command line, using a Makefile, using an IDE? Can you make a copy of a working file and compile that without warnings? – Dave Tweed Sep 25 '13 at 13:04
  • @Dave Tweed: I am using the MPLab IDE v8.88, using the "rebuild" button. I don't understand what you mean about making a copy of a working file. Note that I edited the C compiler: I'm using Hi-Tech ANSI C Compiler, not C18. – Bob Sep 25 '13 at 13:16
  • Take a file that compiles without warnings, and make a copy of it with a different name. Can you compile it without warnings? Are there per-file settings in the IDE itself that might be suppressing warnings? – Dave Tweed Sep 25 '13 at 13:19
  • @Dave Tweed: I'm not following where you're going with the build a copy of the file, and I'm sure it's my own ignorance: if I cope and paste in the current project and add another file, I'll get errors because I'll have the same function names multiple times, and if I create a new proj, I cant build because it won't have main, etc. Can I compile single C files that are missing main()? If so, how? – Bob Sep 25 '13 at 13:38
  • Okay, I did try pasting one of the lines that threw the warning code into another file, and it throws the warning there too. Then I tried scoping that line globally (outside of the function), and there was no warning. We're getting closer, but we're not there yet... – Bob Sep 25 '13 at 13:39
  • Can you cut & paste this entire function into one of the files that compiles without warnings and has similar const declarations, and see if you get these warnings there? – user28910 Sep 25 '13 at 13:48
  • Yes, add a copy of the file to the project, and ignore those other errors. Or rename the functions in the copy, it doesn't matter. The point is to find the minimum set of differences between two files that make the difference between getting that specific warning or not. – Dave Tweed Sep 25 '13 at 13:56
  • @Bob could you past the void function where it's called? We don't need all the function content, but perhaps few first lines, and some code that calls the function – woliveirajr Sep 25 '13 at 14:33
  • I solved it, see below. Hopefully the next guy that has this error won't be left with 1 google search results: a russian web site with no useful info... Thanks again for the help – Bob Sep 25 '13 at 14:41

3 Answers3

2

I got it, and thanks so much for everyone's help!

The declarations that are not throwing warnings are either arrays, or they are declared static const uint8/16's. For some reason, the Hi-Tech C compiler is fine with const int/char's, const uint8/16's that are arrays, but not const uint8/16's unless declared as static const uint8/16.

Bob
  • 848
  • 2
  • 9
  • 21
2

You should appreciate that due to the odd architecture of the PIC16/18, a "const" qualifier is an instruction to place that variable in Flash instead of RAM, not an instruction to tell the compiler that it's not allowed to be changed.

If you're trying to initialise the value of an auto variable that's local to a function then you ARE trying to change it at run-time because it's going to try to write that initialisation value to the variable (which is stored in Flash and is therefore not (easily) writable) every time the function executes. The reason it works when the variable is declared static is because static variables that are local to functions are only ever initialised once, so there is no logical inconsistency for the compiler to whine about. My guess is that the const arrays are being treated in the same way.

markt
  • 4,936
  • 2
  • 15
  • 13
  • This doesn't explain why when you use a char or int as opposed to int16/8 or uint16/8 it doesn't throw the same warning, but does have the potential to explain why globally scoped const int16/8's weren't giving the error. It's a weird, compiler specific issue. Are you sure these are placed in flash? I keep wondering about that for the PIC, and went through some disassembly once, but never was 100% on it. I thought the Pics had code space and memory space, and instructions were 14 bits long or something weird like that... – Bob Sep 26 '13 at 12:21
  • 1
    PIC16's have 14-bit flash (6-bit opcode, 8-bit operand); PIC18's have 16-bit flash. Both store const variables in flash; some PIC16 compilers can be told to pack strings 2x7-bit into each 14-bit word, which can make it hard to read when debugging. Both families have completely seperate code and data spaces; read the memory chapters of any PIC16/18 datasheet for a good explanation. I can't explain the "int/char works, int8/int16 doesn't" problem, that doesn't make sense at all - however you choose to describe a char, the compiler should behave exactly the same way. – markt Sep 27 '13 at 07:44
  • It occurred to me that the reason the auto const arrays weren't throwing errors is because a const char[] is actually a const char *; the pointer resides in ram and the data it references resides in flash. The pointer can be re-written (to point to the same object in flash) every time the function executes without causing any issues. Also, you could try resolving the char-v-uint8 issue by using a #define instead of a typedef. – markt Sep 28 '13 at 21:53
1

I think the root problem is your expectation of how CONST works with this compiler on this processor. These things are not variables as you seem to be expecting from your description. They are very likely implemented as constants in program memory, which is essentially read-only. These things can't be changed at run time. The error you are getting is probably related to runtime code attempting to write to the CONST, not the definition of the CONST.

Olin Lathrop
  • 310,974
  • 36
  • 428
  • 915