C++ question on constants

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

regarding this

static const int k1 = 32767
#define k1 123

with
C++ will the compilers use the same code for these two cases?
And if plain C (C99) ?
(setting aside size_t)

I guess #define has a scope of the entire file? Module? And static const in a class has just that scope? and so on. Implicit secret rules.

then...
Will some compilers create read-only storage for this constant if the target CPU has no "load immediate" for a number that large?
If the constant were smaller, say, 12 (or 255 is another case), and it might make a difference for some kinds of CPUs? (The range of a load immediate is small in some CPUs, like 5 bits or so)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is your question about AVR micro-controllers ?

The #define is for the entire file.
The #define can be in a *.h file for the entire project.
A #define can be anything. The compiler only replaces the text.
The number 123 is normally a 16-bits integer.

The word 'static' outside a function is to use the variable only in that file.
It is possible to declare a constant in the read-only flash area (with the code). For that you will have to do some reading about 'PROGMEM' and 'pgm_read_byte'.

The ATtiny and ATmega chips are 8-bit chips. If constant values are 0...255, they could be declared as 8-bit. That would create small and fast code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

(posted in this forum as this didn't seem pertinent to the forums for GCC or Studio).

static const int x = 123
vs
static int x = 123

is the confusing part. If the target CPU has flash for code/data, vs. a CPU with flash (non-volatile), vs. a CPU with flash and storage initializers that copy from flash to RAM in the C startup.

But more fundamental,
static const int x = 123
inside a C++ class but not in a function, is my basic inquiry.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can find a lot elsewhere, like this: http://www.learncpp.com/cpp-tuto...

Or you could try avr-g++ to compile a test program, and see where everything is located.

But since a class is located in ram, a constant in a class is also in ram. It is the program code that prevents writing it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A static member of a class is shared among all objects of that class type.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
But since a class is located in ram, a constant in a class is also in ram.
Not necessarily. Since the variable is static, it is not part of instance of the class, it belongs to the class itself, so the compiler might be able to put it into read-only memory. In C, the compiler is allowed to put a const variable into read-only memory, but I am not sure if this also holds with C++. It has const_cast which can remove the const-ness of a variable which may prevent the use of read-only memory.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
...Since the variable is static, it is not part of instance of the class, it belongs to the class itself...

You are right (learn something every day).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

with
C++ will the compilers use the same code for these two cases?

Winding back to the first question. You need to understand the difference between pre-processing and compilation. The compiler will never "see" the #define'd 'k1' because by the time the text is passed to the compiler itself the CPP will already have done a string substitution and replaced all occurrences of k1 with 123. That is:

static const int k2 = 32767;
#define k1 123 

int main(void) {
  OCR1A = k1;
  OCR1A = k2;
}

After pre-processing the C compiler sees:

static const int k2 = 32767;


int main(void) {
  (*(volatile uint16_t *)((0x2A) + 0x20)) = 123;
  (*(volatile uint16_t *)((0x2A) + 0x20)) = k2;
}

'k1' wasn't a variable and it never really existed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since he specifically mentioned C++, I think the OP may be asking whether the feature of C++ whereby "static const" variables are optimized entirely out of the final output (so long as nothing tries to take their address), and behave as if they were #defines (as far as codesizes go). I was about to say that I had vague recollections of this not working with the WinAVR C++, but I happened to have a suitable module in my current project that I could try the concept out in, and by golly, it IS treated as if it were a #define. My code:

// buttonMonitor.cpp - This module polls the "Input Mode" button
//
#include "task.h"
#include 

static const uint8_t PINTOGGLE = 0x10;

PERIODICTASK(Watchbutton, 100)
{
    // The button is wired to pull PortD bit 5 LOW when actuated:
    //
    if (0 == (PIND & _BV(5)) ) {
        DDRD ^= PINTOGGLE;
    }
}

The result:

PERIODICTASK(Watchbutton, 100)
{
    // The button is wired to pull PortD bit 5 LOW when actuated:
    //
    if (0 == (PIND & _BV(5)) ) {
    25d6:	4d 99       	sbic	0x09, 5	; 9
    25d8:	04 c0       	rjmp	.+8      	; 0x25e2 
        DDRD ^= PINTOGGLE;
    25da:	8a b1       	in	r24, 0x0a	; 10
    25dc:	90 e1       	ldi	r25, 0x10	; 16
    25de:	89 27       	eor	r24, r25
    25e0:	8a b9       	out	0x0a, r24	; 10
    25e2:	08 95       	ret

000025e4 <_GLOBAL__I_ButtonMonitor>:
    }

Also, the "PINTOGGLE" symbol doesn't show up in the link map file, so it looks like it was truly zero cost.

One advantage of the static const approach vs. #define is that a normal debugger will typically be able to show you the definition of the "define". In AStudio, you'll have about a 30% chance of this working, depending on unknown moon phases. But that's better than the zero percent chance you have of mousing over a #define-d symbol and seeing what it is.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
But more fundamental,
static const int x = 123
inside a C++ class but not in a function, is my basic inquiry.

You have not made the variable a member of a class. A static variable inside a class definition is quite different from a static variable inside a .cpp file.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

at this ripe old age, I do know the difference between the preprocessor and the compiler 8^)

From this chat, I surmise that
static const int x = 123
when in a class but outside of a function, can be stored as an operand in flash and not in RAM or can be in flash to initialize the run time value in RAM- or can be handled like a #define is, where the constant can sometimes/always be part of an instruction's op code (load immediate, etc.)

I believe it's compiler dependent, compiler option dependent, and target CPU dependent. If I'm wrong, please advise.

My question began when reading on the aforementioned website tutorial on c++ for embedded, where the author says it "is poor form and not recommended" to #define "macros" as he called this preprocessor text replacement.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I believe it's compiler dependent, compiler option dependent, and target CPU dependent. If I'm wrong, please advise.
Yes, since the c/c++ standards don't deal with different memory address spaces.

Quote:
My question began when reading on the aforementioned website tutorial on c++ for embedded, where the author says it "is poor form and not recommended" to #define "macros" as he called this preprocessor text replacement.
It's generally considered poor form because a const gives you things like type safety and scope when compared to a #define.