Need to conditionally declare library

01 Mar 2011

I'd like to declare a library function (EthernetNetIf) in one of two ways, according to whether a "dhcpenable" flag is set or not.

If the flag is set, the library should be declared simply as

  EthernetNetIf eth();

Whereas, if the flag is not set, then I need to declare it in the following way:

  EthernetNetIf eth(
    IpAddr(192,168,1,158), //IP Address
    IpAddr(255,255,255,0), //Network Mask
    IpAddr(192,168,1,254), //Gateway
    IpAddr(192,168,1,2)  //DNS
  );

The required form is not known until run time, which means that these declarations have to live inside an executable routine. I can't put them in a static header, as is normally done.

While the compiler is OK with a library declaration inside an executable routine, it gets very unhappy when a library declaration is prefaced by a conditional test.

If a condition precedes the library declaration, the library declaration seems to be ignored by the compiler. The first reference to one of its members gives a compiler error. The following, for example, does not work:

#include "mbed.h"
#include "EthernetNetIf.h"

int main() {
  int dhcpenable = 1;

  if(dhcpenable) EthernetNetIf eth();
  else {
    EthernetNetIf eth(
      IpAddr(192,168,1,158), //IP Address
      IpAddr(255,255,255,0), //Network Mask
      IpAddr(192,168,1,254), //Gateway
      IpAddr(192,168,1,2)  //DNS
    );
  }
  EthernetErr ethErr = eth.setup();
  if(!ethErr) printf("Setup OK\r\n");
}

The resulting compiler error says that "Identifier 'eth' is undefined (E20)".

- - -

I was able to distill this compiler behavior into the following simple test programs:

// This compiles cleanly
#include "mbed.h"

int main() {
  DigitalOut myled(LED1);
  myled = !myled;
}

//This generates a compiler error
#include "mbed.h"

int main() {
  if(1) DigitalOut myled(LED1);
  myled = !myled;
}

The top case compiles cleanly; the bottom case generates an "undefined identifier" error for myled.

- - -

Any suggestions on how to work around this?

01 Mar 2011

Im guessing by initializing myled inside the "IF" statement would render its scope within that IF statement. Once you're out of that statement, the variable myled is destroyed, thus the compiler complains

01 Mar 2011

The problem is that you constructed the EthernetNetIf inside the scope of your if statement. The object no longer exists outside of that scope.

You could do in two ways

#define DHCP   // Use DHCP

#if DHCP

EthernetNetIf eth();

#else

EthernetNetIf eth(
      IpAddr(192,168,1,158), //IP Address
      IpAddr(255,255,255,0), //Network Mask
      IpAddr(192,168,1,254), //Gateway
      IpAddr(192,168,1,2)  //DNS
    );

#endif

or

  EthernetNetIf *eth;

  if(dhcpenable) eth = new EthernetNetIf();
  else {
    eth = new EthernetNetIf(
      IpAddr(192,168,1,158), //IP Address
      IpAddr(255,255,255,0), //Network Mask
      IpAddr(192,168,1,254), //Gateway
      IpAddr(192,168,1,2)  //DNS
    );
  }
  EthernetErr ethErr = eth->setup();

don't forget when done with eth constructed this to destroy it with

  delete eth;

otherwise you'll get memory leaks.

01 Mar 2011

And if you need to preserve the eth.setup() syntax you can create a reference to *eth (alias).

01 Mar 2011

Thanks for the suggestions. The new object approach works well.

Regards, hb