tags:

views:

492

answers:

4

Hi,

We are using a macro wrapper to Bind Where Parameter function.

#define bindWhereClause(fieldName, fieldDataType, fieldData) _bindWhereClause(fieldName, fieldDataType, sizeof(fieldData), &fieldData)

void _bindWhereClause(const char *name, int dataType, int dataSize, void *data)
{
  // Implementation
}

Database.bindWhereClause( "FIRST_NAME", SQL_VARCHAR, name.getFirstName());

When I tried to call the macro with a function as parameter (as above) I am getting the error message "error: non-lvalue in unary `&'".

I am able to call the macro with normal variables like

Database.bindWhereClause( "FIRST_NAME", SQL_VARCHAR, firstName);

How to resolve this? Do I need to use inline functions instead of macro?

Appreciate your help in advance.

Thanks, Mathew Liju

+1  A: 

For this case you will be just fine using an inline function. It is much better in general and you should use inline functions unless using macros is absolutely necessary.

sharptooth
It is, however, unlikely to work in this particular case.
caf
+1  A: 

The macro expands to:

_bindWhereClause("FIRST_NAME", SQL_VARCHAR, sizeof(name.getFirstName()), &name.getFirstName())

You can't take the address of the return value of a function, so that's invalid. You can take the address of a variable or argument, so yes, turning it into a function with actual arguments would work.

Chuck
yves Baumes
... as you are able to do my_vector[0] = "hello world" when your vector contains string
yves Baumes
You are, of course, right. I couldn't find a way to say it any more precisely without distracting from the actual point, but I was specifically talking about a returned *value* as opposed to a returned *reference*.
Chuck
+3  A: 

You can't take the address of the return value of a function - it is ephemeral.

You need to use a real variable:

Nametype first_name = name.getFirstName();
Database.bindWhereClause( "FIRST_NAME", SQL_VARCHAR, first_name);

// ... and maybe name.setFirstName(first_name); here

Using an inline function would make it compile but it is unlikely to actually work. Presumably this is followed by something like:

Database.execute();

...which expects the objects whose addresses you passed earlier to still be valid. If you use an inline function instead of a macro, those objects will no longer exist, since they were just local to the inline function which has already exited.

caf
Yes Caf, I am executing the query in the next step. Thanks for the suggestion, I have implemented in this way.
Liju Mathew
A: 

Why not write a wrapper class around Database.

Check out the Decorator pattern: http://en.wikipedia.org/wiki/Decorator_pattern

Martin York