Shop OBEX P1 Docs P2 Docs Learn Events
All_those#constants — Parallax Forums

All_those#constants

ErlendErlend Posts: 612
edited 2015-01-03 05:16 in Propeller 1
I take pleasure in writing code in a style where it is as self explanatory as possible, even to the non-Spin enabled, almost like pseudo code. With this goes a verbouse style with full naming of varables and constants. Yeah, I know, some call it bloated code. Fortunately compilers often take care of that and leave the excess fat behind in the source code. I guess that is basically true for Spin too, but I am not sure to what extent.
For instance, the result of concistantly having full-named constants is that I end up with a large amount of constant definitions. To keep the top level code lean and legible I would like to move most CON definitions to a dedicated Object, such that they can be used by means of Cdefs#a_constant. But, to do this every Method using these constants need to include the 'Cdefs' in their OBJ declaration. How does this end up affecting code size?
Btw, I wish there was a similar way to do this for Varables too.

Erlend

Comments

  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-01 05:09
    Using constants from another object does not increase the binary code size. However, Spin requires that objects must have at least one public method, so you will have to define a dummy method in your constant object. This will add 4 bytes to each object that references the constant object plus 12 bytes in the constant object itself.
  • Heater.Heater. Posts: 21,230
    edited 2015-01-01 06:03
    Having long constant and variable names does not increase the size of the final binary image. There are no symbols in there.

    Meaningful function/variable/constant names is a good idea. When that becomes "verbose" is subjective I guess.
  • msrobotsmsrobots Posts: 3,709
    edited 2015-01-01 06:44
    @Erlend,

    I did this and it is working without memory overhead at all. Almost. Including the object cost a couple of longs.

    If you reduce your 'common' object just to contain a CON section you can include it wherever and as often you want. CONstants get resolved at compile time.

    Putting 'common' used things besides CCONstant definitions into a 'common' object is a little bit more trickier, but doable.

    If you include the same object in multiple other (sub)objects in your project the spin compiler will sort of prune it.

    It will reduce it to ONE code section and ONE data section. each objet will have its own VAR section.

    So code and all references to DAT sections are shared or common to all 'instances' of the same object. VARiables are bound to the instance of the object.

    So as long as you avoid VAR sections, you can include your object as often as you want and it will just be ONE time in the created binary. But each instance has its own VAR section. Keeping that in mind you can build some nice helper/common objects.

    This is a pretty neat feature of spin.

    Enjoy!

    Mike
  • msrobotsmsrobots Posts: 3,709
    edited 2015-01-01 07:21
    Sadly no spin compiler supports obj@label. I really like referencing SER#baud9600 as a constant of my instance of the whateverserialobject.spin defined as SER in the OBJ section.

    I also can call a procedure/method/function or whatever you call it by SER.whatever(parameters)

    what I can not do is referencing the address of something in the (sub)object.

    example:

    now I have to do

    PUB getVarAdr
    return @myVar

    assuming myVar is a label inside the sub object. Either in DAT or VAR section

    to use this in my main program I need to do something like this:

    current := long[SER.getVarAdr]

    wouldn't it be nicer to have direct access to the address and skipping the procedure getVarAdr?

    current:=long[SER@myVar]

    could do the same and you do not need a function/method/procedure to access the address.

    Anyways!

    Mike
  • Heater.Heater. Posts: 21,230
    edited 2015-01-01 07:32
    Some would argue that giving external objects direct access to an objects internal properties is a poor design design technique. Encapsulation is desirable from a software development, maintenance and reuse point of view as it allows the implementation of an object to be changed without impacting any other code that uses it.
  • ErlendErlend Posts: 612
    edited 2015-01-01 23:40
    Heater. wrote: »
    Some would argue that giving external objects direct access to an objects internal properties is a poor design design technique. Encapsulation is desirable from a software development, maintenance and reuse point of view as it allows the implementation of an object to be changed without impacting any other code that uses it.
    I would think that good programming style is maintained as long as the Cdefs object is used similar to the C's #define function - as just a container of definititions?

    Erlend
  • Heater.Heater. Posts: 21,230
    edited 2015-01-02 02:23
    Erlend,

    Personally I have no problem with constant definitions in an object that does nothing but hold constant definitions. Global constant definitions as it were.

    We might ask though, "why do that?". Presumably those constants are describing the nature of something and that something is probably related to some functionality, subsystem, of your program. And presumably that functionality/subsystem is itself implemented in an object. So why not put the constant definitions in the object they relate to? Why have them "globally" defined?

    I can think if some cases where this is not the case though:

    1) Truly global constants that potentially span all other objects. Things like mathematical constants, PI, E, and so on.

    2) Constants that relate to things external to the Propeller in your project. Things like, well I don't know, perhaps the baud rate used by some external gadget, Basically constant that describe objects external to the Propeller and in Spin program and hence don't have a natural place to live in your code.

    3) Cross cutting concerns. Perhaps you have one pin dedicated as an emergency stop output that any other object can raise when it gets into an error situation. (Not a good example as I imagine it's better to create an emergency stop object here and include that in all the other objects.

    One can make an argument that all the constants that define the interface between the Prop and the outside world should be defined in a global constant object rather than being spread around other objects. So for example a single configuration object would contain all the definitions of which pins are used by which interface, UART, PWM, ect, etc. This way you have a single place to look to when moving code from platform to platform or rearranging hardware on your bread board. I think Cluso is a big fan of this.

    Can anyone suggest other use cases for global constants?
  • ksltdksltd Posts: 163
    edited 2015-01-02 15:20
    The real problem is that Spin has no scoping mechanisms that are useful. And it has no constants, only named numbers. And there are plenty of named numbers with global scope - True and False come to mind.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-01-02 18:45
    Heater. wrote: »
    Can anyone suggest other use cases for global constants?
    I use an object called sysdefs.spin that defines the memory locations for system variables that reside in high memory. This is also used by drivers for mailboxes, but it also contains environment variables and a system heap that is used by higher level programs.
  • ErlendErlend Posts: 612
    edited 2015-01-03 05:16
    Heater. wrote: »
    Erlend,

    Personally I have no problem with constant definitions in an object that does nothing but hold constant definitions. Global constant definitions as it were.

    We might ask though, "why do that?". Presumably those constants are describing the nature of something and that something is probably related to some functionality, subsystem, of your program. And presumably that functionality/subsystem is itself implemented in an object. So why not put the constant definitions in the object they relate to? Why have them "globally" defined?

    I can think if some cases where this is not the case though:

    1) Truly global constants that potentially span all other objects. Things like mathematical constants, PI, E, and so on.

    2) Constants that relate to things external to the Propeller in your project. Things like, well I don't know, perhaps the baud rate used by some external gadget, Basically constant that describe objects external to the Propeller and in Spin program and hence don't have a natural place to live in your code.

    3) Cross cutting concerns. Perhaps you have one pin dedicated as an emergency stop output that any other object can raise when it gets into an error situation. (Not a good example as I imagine it's better to create an emergency stop object here and include that in all the other objects.

    One can make an argument that all the constants that define the interface between the Prop and the outside world should be defined in a global constant object rather than being spread around other objects. So for example a single configuration object would contain all the definitions of which pins are used by which interface, UART, PWM, ect, etc. This way you have a single place to look to when moving code from platform to platform or rearranging hardware on your bread board. I think Cluso is a big fan of this.

    Can anyone suggest other use cases for global constants?

    Heater,

    In this particular project I have organized it such that many of the cogs are dedicted to reading and writing to the outside world, e.g. ADC, LCD, switches, etc., and they all operate around one single 'real-time database' for storing and retrieving. This 'database' is owned by the top level Main and is nothing more than a set of global variables that are accessed by means of LONG[] from the various cogs. This is going on sort of in the background, whereas algorithms/logic/sequencing is executing in the Main and a few other cogs, and they do not have to worry about I/O, its taken care of. I am kind of emulating the use of true global variables. Often constants go hand-in-hand with variables, e.g. together with Value goes RangeMin and RangeMax, and EngineeringUnit. So when I need global variables I need global constants. I could implement this as an object-based real-time database and cover the physical I/O functionality quite well in that way, but I also experience the need for global constans in other respects, such as with user interfaces.
    I guess this is an answer to your 3), and for 2) and 1) my answer is simply yes.

    My rudimentary coding background is with ObjectPascal for the office, and with various object-based propriretory SCADA and Supervisory systems for the real-time world. It's a long time ago, but I probably still want to structure the code the way I am used to. Maybe I am pushing Spin out of her comfort zone.

    Erlend
Sign In or Register to comment.