Troubles using const, not sure if I do it correctly..

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

Hey all,

 

I've been in the AVR scene for a few years, but I keep myself in the background because everytime I ask a question I get an answer that more or less says that I'm not allowed around these parts unless I get a multi-super-mega-somethingawesome-degree out-of-all-sorts-of-different-directions..

 

Well, I'm tired of that.. I know I'm not a superpro at programming, I know I don't know a whole lot when it comes to programming, I know I have troubles finding what I need simply because I dont know it exists.. I'm NOT the kind of person who can read through hundreds of pages with declarations of functions, code etc. I'm a simple hobbyist who want to try and learn things in the way I actually learn and remember things.. So with that said, PLEASE be kind when I ask questions..

 

I'm not outright stupid or play silly, I just dont know and I need your help. If your time is worth so much more than to answer simple questions, then please use your time for something else.

I feel sad for having to write this, but normally I dont get any help.. I just get sneezed at and told to read a whole datasheet. I have no problems reading through a datasheet, but I need to know what I'm searching for. So once again, PLEASE be kind.

 

-----

 

On to the question.. I'm having troubles "converting" Arduino code to regular C code and I understand that Arduino has implemented some functions of their own and "enhanced" the C language with some extras.. Ok, nothing wrong with that!

 

However, when trying to convert the code from Arduino to regular C code there are some parts where I need to find a suitable code or function that can replace the special part.. So I have the following code, which comes from Freetronics, used for a sensor shield.

 

struct input_ranges {
  int sensor_state;
  const String label;
  int range_bottom;
  int range_optimum;
  int range_top;
};
const input_ranges ranges[] {
  { STATE_SHORT,        "Shorted",         0,    0,  162 },  // 0
  { STATE_NORMAL,       "Normal",        163,  326,  409 },  // 1
  { STATE_TAMPER,       "Tamper",        410,  495,  551 },  // 2
  { STATE_ALARM,        "Alarm",         552,  609,  641 },  // 3
  { STATE_ALARM_TAMPER, "Alarm+Tamper",  642,  675,  848 },  // 4
  { STATE_CUT,          "Cut",           849, 1023, 1023 },  // 5
  { STATE_UNKNOWN,      "Unknown",      1024, 1024, 1024 },  // 6
};

This is not directly usable in AtmelStudio. I've tried to come up with changes, which I'm of course not completely 100% on if that it's the right way to do it. But at least the compiler doesn't complain, so I could at least run the code and see if I get the result that I want. I haven't done that yet, as I'm struggling further, so I thought I would ask here for a solution if anyone understands the problem.

 

I changed the code above to the code below;

struct input_ranges {
	int sensor_state;
	char* label;
	int range_bottom;
	int range_optimum;
	int range_top;
};

const char input_ranges[] = {
	{ SENSOR_STATE_SHORT,        "Shorted",         0,    0,  162 },  // 0
	{ SENSOR_STATE_NORMAL,       "Normal",        163,  326,  409 },  // 1
	{ SENSOR_STATE_TAMPER,       "Tamper",        410,  495,  551 },  // 2
	{ SENSOR_STATE_ALARM,        "Alarm",         552,  609,  641 },  // 3
	{ SENSOR_STATE_ALARM_TAMPER, "Alarm+Tamper",  642,  675,  848 },  // 4
	{ SENSOR_STATE_CUT,          "Cut",           849, 1023, 1023 },  // 5
	{ SENSOR_STATE_UNKNOWN,      "Unknown",      1024, 1024, 1024 },  // 6
};

It now compiles without errors, but I do get a couple of warnings. For each row in the lower part of the code I get the following warning;

 

braces around scalar initializer [enabled by default]
(near initialization for 'input_ranges[0]') [enabled by default]

I know that warnings are not as serious and you can still compile and run the code, however it might not give the result you wanted while it still works. So I just wanted to see if you could tell me why this is happening, is the code wrong? And what may be done to remove this warning?

 

There might be other ways to do what the code above can do, but I learn by trying. However, when its not working I dont really understand why. Normally I can fiddle around and eventually get it to work, but I seem to have lost my "force" in this case.

Also, on another note. Apart from moving "SENSOR_STATE_UNKNOWN" from the end to the beginning of the array, what is different between the following two code samples?

 

Code 1

struct sensor {
	char *label;
	char analog_input;
	char status_output;
	char last_state;
};

const char sensor[] = {
	{ "A", 0, 4, SENSOR_STATE_UNKNOWN },
	{ "B", 1, 5, SENSOR_STATE_UNKNOWN },
	{ "C", 2, 6, SENSOR_STATE_UNKNOWN },
	{ "D", 3, 7, SENSOR_STATE_UNKNOWN },
};

 

Code 2

struct sensor {
	char last_state;
	char *label;
	char analog_input;
	char status_output;
};

const char sensor[] = {
	{ SENSOR_STATE_UNKNOWN, "A", 0, 4 },
	{ SENSOR_STATE_UNKNOWN, "B", 1, 5 },
	{ SENSOR_STATE_UNKNOWN, "C", 2, 6 },
	{ SENSOR_STATE_UNKNOWN, "D", 3, 7 },
};

 

Code 2 compiles without problems, while Code 1 gives the following;

initializer element is not computable at load time
(near initialization for 'sensor[0]')
initializer element is not computable at load time
(near initialization for 'sensor[1]')
initializer element is not computable at load time
(near initialization for 'sensor[2]')
initializer element is not computable at load time
(near initialization for 'sensor[3]')

 

Don't take me as an ignorant brat or anything similar, I'm kind of slow in learning and I need to learn and remember things in a certain way. Please help me out if you have time and if you can.

Thanks!

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

 

 

We really didn't need to read the other fluff - especially when you make assertions without evidence. Anyways, Arduino is C++. You can also do C++ in Atmel Studio. String is a C++ type, so using that in C will cause problem - you've gathered this. 

typedef struct { 
    int sensor_state;
    char* label;
    int range_bottom;
    int range_optimum;
    int range_top; 
    
} Input_ranges;

    const Input_ranges input_ranges[] = { { SENSOR_STATE_SHORT, "Shorted", 0, 0, 162 },
    // 0 { SENSOR_STATE_NORMAL, "Normal", 163, 326, 409 },
    // 1 { SENSOR_STATE_TAMPER, "Tamper", 410, 495, 551 },
    // 2 { SENSOR_STATE_ALARM, "Alarm", 552, 609, 641 },
    // 3 { SENSOR_STATE_ALARM_TAMPER, "Alarm+Tamper", 642, 675, 848 },
    // 4 { SENSOR_STATE_CUT, "Cut", 849, 1023, 1023 }, 
    // 5 { SENSOR_STATE_UNKNOWN, "Unknown", 1024, 1024, 1024 },
    // 6 };

Hopefully I got the above correct. So, we typedef our structure - this makes it a 'type' just like using an int or char. We then declare the array of type and initialise them. This is standard C - the standard reference is the K & R book.

 

I don't use Atmel Studio too much - I thought there were means of importing an Arduino project and libraries and having the luxury of the better editor etc.... I know TI does.

Last Edited: Sat. May 2, 2015 - 11:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
const char input_ranges[] = { ...

This defines an array of type char and name "input_ranges".
But you need array of structures!

 

// define array of structures 
// type = struct input_ranges
// name = ranges 
const struct input_ranges ranges[] = { ...

 

Last Edited: Sun. May 3, 2015 - 08:34 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for your replies! Just woke up and trying to fit the code in the editor.. :)

 

It seems that the following code;

typedef struct {
	int sensor_state;
	char* label;
	int range_bottom;
	int range_optimum;
	int range_top;
	
} input_ranges;

const input_ranges ranges[] = {
	{ SENSOR_STATE_SHORT,			"Shorted",		0, 0, 162 },				// 0
	{ SENSOR_STATE_NORMAL,			"Normal",		163, 326, 409 },			// 1
	{ SENSOR_STATE_TAMPER,			"Tamper",		410, 495, 551 },			// 2
	{ SENSOR_STATE_ALARM,			"Alarm",		552, 609, 641 },			// 3
	{ SENSOR_STATE_ALARM_TAMPER,	"Alarm+Tamper", 642, 675, 848 },			// 4
	{ SENSOR_STATE_CUT,				"Cut",			849, 1023, 1023 },			// 5
	{ SENSOR_STATE_UNKNOWN,			"Unknown",		1024, 1024, 1024 },			// 6
};

Slightly edited due to that the comments went on wrong lines, so commenting out most of the array ;) But its basically the code from Kartman.

But it seems that this code compiles without any hickups at all. I haven't tried the code yet, I will do it later on today, but if it compiles ok then it have a great chance of working I guess. Right? I could of course give another result than what I'm expecting as well, but we'll see :)

 

Visovian

Thanks for that! Unfortunately I get the following error when I add "struct" to the above code like so;

const struct input_ranges ranges[] = {

Error

array type has incomplete element type

 

 

Ok, so now it "works" in terms of compiling, I don't get the warnings anymore. But why is that? Is it thanks to the "typedef struct" part that tells the compilar that input_ranges should look like it does? I guess you've written this more or less Kartman, but just wanted to clarify.. Just to learn :)

 

May I ask what other IDE you use Kartman? Even if I might not use that, it's just fun to know what others use.

Many thanks for the explanation you've given in your entry, I really appreciate that! I also looked up the K & R book and put it on my "to buy" list. I guess I'll buy it when I get paid this month :) What makes it extra interesting is the "only" 274 pages. Normally it feels like programming books are like 500+ pages. I might be able to get through this one ;) Thanks!

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

const char

Was the main problem. Your struct is not a char, so you can't declare and initialise it as such.

 

const struct input_ranges ranges[] = {

You can't do this if your struct has been typedef'd. There's arguments whether to typedef or not to typedef. I typedef as it makes for less typing - no need to add 'struct' when you use it. There's plenty on the inter webs that describe the whole shebang.

 

Maybe someone else can jump in an explain the rules. The K&R book is a bit of a dry read, but it is the C reference.

 

What other IDE's do I use? Considering I don't do much on Atmel on recent times, at work I use IAR, but apart from the compiler, the IDE is dated and the debugger buggy. For other brand micros, these tend to use an Eclipse based IDE. Atmel Studio is the odd one out - being based on Visual Studio - seems to work ok, but takes ages to load.

 

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

There seems to be a stylistic habit of declaring the struct, the typedef, and the variable of the new type all in one declaration or statement. I think it is easier if the struct is one declaration, then the typedef of that struct tag is another declaration, then the variable of the new type is another declaration. I dont even like the tendencu to declare a list of ints or floats sparated by commas. If they are each on their own line you can add the comment with where they are used etc. I'd attempt to give an example, but I'd get it wrong, and I'd never live it down.

 

 

Imagecraft compiler user

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

toffie wrote:

 

Visovian

Thanks for that! Unfortunately I get the following error when I add "struct" to the above code like so;

const struct input_ranges ranges[] = {   

Error

array type has incomplete element type

 

I took your code from your post #1 and changed only line xx.

Got no error.

 

struct input_ranges {
	int sensor_state;
	char* label;
	int range_bottom;
	int range_optimum;
	int range_top;
};


const struct input_ranges ranges[] = {          // line xx
	{ SENSOR_STATE_SHORT,        "Shorted",         0,    0,  162} ,  // 0
	{ SENSOR_STATE_NORMAL,       "Normal",        163,  326,  409 },  // 1
	{ SENSOR_STATE_TAMPER,       "Tamper",        410,  495,  551 },  // 2
	{ SENSOR_STATE_ALARM,        "Alarm",         552,  609,  641 },  // 3
	{ SENSOR_STATE_ALARM_TAMPER, "Alarm+Tamper",  642,  675,  848 },  // 4
	{ SENSOR_STATE_UNKNOWN,      "Unknown",      1024, 1024, 1024 },  // 6
	{ SENSOR_STATE_CUT,          "Cut",           849, 1023, 1023   }// 5
};

 

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

Until you get hold of K&R try this link. It's a pretty good reference for the "C" language.

 

Greg