6

Most Micropython ports contain a 'micropython' module, which has a specific function called 'const()'. I am led to believe it behaves a lot like '#define' in C, however, it only accepts integers. Does anyone know why this is? You can declare float constants in C, so why is this unavailable in micropython?

I want to efficiently store values which are used to convert between units, but many of them are float values... (I thought about multiplying them by 10^x and then just dividing by that at runtime, but this will likely take just as long as storing the float in a variable and letting the code use the lookup table).

Any ideas why we can only declare integers with micropython.const()?

Cheers :)

birdistheword99
  • 179
  • 1
  • 15
  • 2
    "it behaves a lot like '#define' in C" `#define` is a pre-processor command and therefore works completely different. – Klaus D. Jan 28 '20 at 10:38
  • 1
    @KlausD.: MicroPython's `const` is recognized by the MicroPython compiler, though, so it behaves a lot more like `#define` than anything you could do in CPython. You can't do any complex macro stuff, but `const` values will be directly substituted into their usage sites (within a module, at least), and non-exported `const`s don't require a storage location. – user2357112 Jan 28 '20 at 10:49
  • ah ok, thanks @user2357112supportsMonica and KlausD, I understand about the preprocessor commands and see the slight difference in usage. Is lack of floating-point support perhaps to do with the different space requirements for integers and floats? – birdistheword99 Jan 31 '20 at 15:01
  • 2
    MicroPython only accepts so called 'small integers' for `const`; 'large' integers (i.e. integers which don't fit in a machine word minus some bits) and floating point values need to be allocated on the heap. `const` replacement etc is done when parsing I think, before compiling. As to your actual question, i.e. why that wouldn't work for heap-allocated objects: I guess technically it could be possible but it might be too hard, not sure.. – stijn Feb 12 '20 at 19:06

2 Answers2

3

With the recent release of v1.19, you can apply const to any object. See PR #8548 for some of the details.

In short, the reason const was initially constrained to ints was simply because the implementation to do so was relatively straightforward.

MattyT
  • 6,531
  • 2
  • 20
  • 17
1

This is by design, the objective of micropython.const() is to save RAM on the MCU therefore according to the docs:
the argument to const() may be anything which, at compile time, evaluates to an integer. http://docs.micropython.org/en/latest/reference/constrained.html?highlight=const()#execution-phase

Jos Verlinde
  • 1,468
  • 12
  • 25
  • How would this save RAM though? I thought unlike CPython, Micropython floats are 32 bits (unlike CPython 64 bits equivalent to a double) so they occupy the same space as an integer? – birdistheword99 Jan 12 '21 at 09:48
  • @birdistheword99, the details are explained in the 1st paragraph of linked reference documentation. ```the compiler will avoid coding a lookup to the name of the constant by substituting its literal value. This saves bytecode and hence RAM. ``` – Jos Verlinde Jan 12 '21 at 13:47
  • MicroPython integers are signed 31-bit `smallint` (1 bit is reserved to flag a pointer, but i can't find a document reference to that) – Jos Verlinde Jan 12 '21 at 14:30
  • thank you for the information, and I apologise for being dumb here, but going back to the original question, if the compiler saves RAM by substituting a lookup to the integer for the actual integer, why can't it do the same thing with a float? Why can't `FOO = const(1.234)` tell the compiler to substitute `FOO` with `1.234` and save bytecode the same way? – birdistheword99 Jan 14 '21 at 10:17