Way to verify consts?

Discuss the Integrated Development Environment (IDE)

Moderators: David Barker, Jerry Messina

Post Reply
SHughes_Fusion
Posts: 219
Joined: Wed Sep 11, 2013 1:27 pm
Location: Chesterfield

Way to verify consts?

Post by SHughes_Fusion » Fri Feb 19, 2016 9:02 am

I'm sure I'm not alone in using equations in my code to calculate timer-related consts and I'm sure I'm also not alone in having occasionally been caught out by the calculated const exceeding the size of the variable type.

I don't know if David is still developing the IDE, but a suggestion would be that it would be nice to flag up any consts where the assigned value exceeds the type size - I'd guess this would have to be at compile time in many cases as clock definitions aren't always in the same file as the const calculation.

However, in the absence of that solution, is there any way I can write my code to flag up any potential problems?

I've tried something like this but it just flags the warning all the time, even when the two are the same:

Code: Select all

Const TimerRValue as longint = 65536 - ( Fosc / PWMRate )
Const TimerReloadValue As Word = TimerRValue
#if TimerRValue <> TimerReloadValue 
  #warning "Timer reload inaccuracy"
#endif
I do tend to check everything manually, but a simple change such as adding a new timer or changing the clock speed can throw things out and means a whole lot more calculations - if you remember.

Any ideas?

User avatar
David Barker
Swordfish Developer
Posts: 1194
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Re: Way to verify consts?

Post by David Barker » Fri Feb 19, 2016 9:35 am

The IDE is always still under development, should user demand require it. However, I think you can achieve what you want in code, which should work fine for byte and word size constants:

Code: Select all

#variable aval = 200
#variable bval = 56
#variable rval = aval + bval

#if rval > $FF 
#warning "rval out of range"
#endif

Const myConst As Byte = rval

SHughes_Fusion
Posts: 219
Joined: Wed Sep 11, 2013 1:27 pm
Location: Chesterfield

Re: Way to verify consts?

Post by SHughes_Fusion » Fri Feb 19, 2016 10:04 am

Thanks, David, I'd not thought of doing it that way.

One question though, are there any compiler constants for the size of the various variables? Not a problem to define them I guess rather than putting in a specific size for each test.

Personally, I'd say this is the sort of check that would be better done in the IDE as adding all the extra code makes things look a bit messy and isn't so clear to someone picking the code up at a later date but I do appreciate it isn't so easy to add.

Also, my initial example probably wouldn't be picked up anyway unless the checking was clever as it would actually result in a negative value if FOsc was too big. This does mean I also have to do an additional check to make sure it isn't negative, or split the calculation in to two parts and check size only.

User avatar
David Barker
Swordfish Developer
Posts: 1194
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Re: Way to verify consts?

Post by David Barker » Fri Feb 19, 2016 10:14 am

> are there any compiler constants for the size of the various variables

I don't understand the question

> Personally, I'd say this is the sort of check that would be better done in the IDE

It would not work for all those people using MPLAB/X to compile their code.

> wouldn't be picked up anyway unless the checking was clever as it would actually result in a negative value

Code: Select all

#if rval > $FF or rval < 0 
#warning "rval out of range"
#endif

SHughes_Fusion
Posts: 219
Joined: Wed Sep 11, 2013 1:27 pm
Location: Chesterfield

Re: Way to verify consts?

Post by SHughes_Fusion » Fri Feb 19, 2016 10:34 am

David Barker wrote:> are there any compiler constants for the size of the various variables

I don't understand the question
I'm thinking rather than #if rval > $FF you could use #if rval > Sizeof(Byte) - it is clearer what you are checking against. Not essential of course, just seems a bit more readable to me.
> Personally, I'd say this is the sort of check that would be better done in the IDE

It would not work for all those people using MPLAB/X to compile their code.
True of course, but I'm thinking of those of us who use the IDE itself - how many do actually use MPLab? I find the Swordfish IDE much slicker to use personally and I've never got on with MPLab X for anything.

That said, could the compiler not do this checking anyway? Granted the IDE could do it - in some circumstances - before compile-time which would be preferable, but the compiler must do the actual evaluation of the expressions so could flag the warnings up.

Really, it is down to how much work you think it will be and how important you think it is. I'd say a lot of less experienced programmers would save a lot of time from checking like this as it is something you learn by experience. It would also be a time-saver for everyone as you don't need to open up calculator and do the sums. It doesn't, however, stop other mistakes such as not checking how rounding affects the calculation.

I've never really explored the plug-ins function for Swordfish. Could I, for example, write one where I specify the timer and frequency I want, it gets the processor and clock selection from the source file and it tells me what dividers I can use and shows the error for each one?

If so, are there any instructions as to how I write a plug-in? :)

User avatar
David Barker
Swordfish Developer
Posts: 1194
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Re: Way to verify consts?

Post by David Barker » Fri Feb 19, 2016 2:01 pm

I haven't written a plugin for ages - John B used to be pretty adept, maybe try contacting him for tips...

http://sfcompiler.co.uk/phpBB3/memberli ... rofile&u=8

Jerry Messina
Swordfish Developer
Posts: 1245
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Way to verify consts?

Post by Jerry Messina » Fri Feb 19, 2016 3:53 pm

I've tried something like this but it just flags the warning all the time...
Something to keep in mind is that the preprocessor can't see "compiler space" declarations, and it doesn't flag any errors when you violate that so things don't work as expected.
I'm constantly forgetting about that myself, and I always run afoul of it wondering why it's "not working".

Any of the '#<whatever>' preprocessor statements only work with other '#' definitions like #const, #var, #define, #option, etc. For example,

Code: Select all

const a = 10
#if (a <> 10)
  #warning "test"
#endif
will never work since 'const a' isn't seen by the preprocessor... you'd have to use '#const a = 10'

On trick I use to check compile-time settings is to use macro functions not to generate any code, but just to verify things. Here's an example...

Code: Select all

clock = 48

const FOSC = _clock * 1000000    // get rid of a zero here to see the macro pass
const PWMRATE = 100

const TimerRValue as longint = 65536 - ( Fosc / PWMRate )
const TimerReloadValue as word = TimerRValue

// compile-time macro for checking various parameters
const
    etError    = 0,
    etWarning  = 1

macro CheckTimerReloadValues()
  if (TimerRValue < 0) then
    checkparam(etWarning, "Timer reload is negative")
  endif
  if (TimerRValue <> TimerReloadValue) then
    checkparam(etError, "Timer reload inaccuracy")
  endif
end macro

// validate timer reload values
// note: since a macro "generates code" the compiler is finicky about where
// you put this statement. if there are variable declarations after it you'll get
// a 'symbol not expected' error, so I usually put it in the "code" section
// towards the end of the module, or in the "module init" section at the very end 
CheckTimerReloadValues()
The nice thing about that is you can do stuff in the macro that you can't use with '#if'.

Here's some of the items you can use with the macro CheckParam() facility

Code: Select all

// values that can be used in CheckParam()
Const
    cpConst              = $01,
    cpVariable           = $02,
    cpArray              = $04,
    cpSize01             = $08,
    cpSize08             = $10,
    cpSize16             = $20,
    cpSize32             = $40,

    cpInteger            = $0100,
    cpReal               = $0200,
    cpString             = $0400,
    cpChar               = $0800,
    cpBoolean            = $1000,

    etError              = 0,
    etWarning            = 1,
    etMessage            = 2,
    etHint               = 3

//example
Macro movlw(val)
   if not CheckParam(val, cpConst or cpInteger or cpsize01 or cpSize08) then
      CheckParam(etError, "Value must be an 8 bit constant")
   endif
   asm
      movlw val
   end asm
End Macro

Post Reply