enum as function parameter

I stumbled into an interesting gap in my understanding of enums in c++ just now. I have a sketch which includes the following:

enum LightContext
{
    Normal,
    Fed,
    Sonar
} lightContext = Normal;

void startSpecials( LightContext newContext )
{
    // ...do something
}

This is not allowed. I found the article on the site that talked about the typical hack for working with enums as function parameters and return types in sketches (put them in a separate header file), but couldn't get the approach to work. As a workaround, I changed startSpecials() to accept an int (which is the underlying type for the enum LightContext) and cast it to a LightContext inside the function. That works, but is kludgy.

I'd like to understand what's causing this problem, and why putting the enum and their related functions in a separate header file is the recommended solution.

FWIW, I'm coming at this from a C# perspective. In that language you can use enums as parameters or return types without doing anything funky. The situation is obviously different in c++, but it's unclear to me why it is.

I'd like to understand what's causing this problem, and why putting the enum and their related functions in a separate header file is the recommended solution.

Well, it's recommended because it works.

Generally, the problem is with how the IDE generates function prototypes and makes other additions to the sketch before it invokes the compiler. You can enable verbose mode (File + Preferences in 1.0+) and see where the build is performed. When verbose mode is used, the build directory is not cleaned up, so you can look at the cpp file that is actually compiled.

The situation is obviously different in c++, but it's unclear to me why it is.

It's not a C++ issue. It's an IDE issue. enums are valid as argument types or return types in C++, too.

You don't have to move the declaration to an include file if you change the declaration of your functio9n:

void startSpecials( enum LightContext newContext )

By including the 'enum' keyword the forward declaration that the IDE puts at the top of your file isn't confused by the not-yet-defined "LightContext". This also seems to work for 'struct'.

I've seen it used too with class and struct to get the thing to make the right prototypes.

I typedef function pointers a lot. I've always had to move those out to includes to get them to work. Is there a way to do something similar with those?

typedef void (*S_Function)();

S_Function someFunction()
{
//  do some stuff and return a function pointer.
}

[quote author=Mark Olbert link=topic=145552.msg1093328#msg1093328 date=1359411746] I'd like to understand what's causing this problem [/quote]

The people who designed the IDE decided that plain straight forward C++ was too scary for novice programmers, but their attempt to make C++ look like Java was only partially successful. If you want to use the Arduino IDE then the mucking about that it does with your code before it compiles it is one of those things that you just have to live with.

Can anyone point towards a good tutorial to get started using something else? I understand the basics of compiling C++ code, but I'm afraid that it's a bit of a black box to me as to how that gets put on the chip and makes anything happen.

what's causing this problem, and why putting the enum and their related functions in a separate header file is the recommended solution.

Whoever proposed that has no understanding of C.

dhenry: Whoever proposed that has no understanding of C.

That seems unlikely.

johnwasser: By including the 'enum' keyword the forward declaration that the IDE puts at the top of your file isn't confused by the not-yet-defined "LightContext". This also seems to work for 'struct'.

I'd tried that in my experimentation, and just tried it again using the following:

enum Junk
{
  One,
  Two,
  Three
} ralph = Two;

void setup()
{
  // This code will only run once, after each powerup or reset of the board
  
}

void loop()
{
  // This code will loops consecutively
  
}

void test( enum Junk a )
{
}

This throws the error "use of enum 'Junk' without previous declaration". At least under version 1.03 of the "enhanced" Arduino IDE (Arduino ERW 1.0.3)

[quote author=Mark Olbert link=topic=145552.msg1095558#msg1095558 date=1359521051] This throws the error "use of enum 'Junk' without previous declaration". At least under version 1.03 of the "enhanced" Arduino IDE (Arduino ERW 1.0.3) [/quote]

I have not heard of the 'enhanced' IDE. What is the difference between the 'enhanced' IDE and the normal one?

It's something I came across while I flailing away at another problem. I was thinking I might be having some Windows 8 64 bit compatibility problems, and it might offer a solution.

As it turns out, my problem was not compatibility related, but I've left the "enhanced" IDE installed. I don't generally use the Arduino IDE anymore, opting instead for the Visual Micro Visual Studio add-in. That's because I do almost all of my programming in VS, and being able to do my Arduino work in that environment is a plus.

The Visual Micro add-in also gives me access to the beta of their Arduino debugger. It doesn't let me step through the code like what I'm used to doing in VS (not sure that's possible on a micro the size of the Arduino), and it has some quirks/oddities, but in many situations its more convenient than scattering a bunch of Serial.print() calls throughout my Arduino code. Particularly if you're used to the way the VS debugging interface works.

The "enhanced" IDE is described at http://arduino.cc/forum/index.php/topic,118440.0.html. The Visual Micro VS add-in can be found at http://www.visualmicro.com/.

  • Mark