views:

177

answers:

4

Hello,

I've got a small bit of code from a library that does this:

#define VMMLIB_ALIGN( var ) var

template< size_t M, typename T = float >
class vector
{

...

private:
// storage
VMMLIB_ALIGN( T array[ M ] );

};

And you can call it by doing

//(vector<float> myVector)
myVector.array;

No parenthesis or anything.

what?


After reading the answers, it appears I should've done more looking. XCode's "Jump to Definition" gave me only one result. Searching the library gave me another:

#ifndef VMMLIB_CUSTOM_CONFIG
#  ifndef NDEBUG
#    define VMMLIB_SAFE_ACCESSORS
#  endif
#  define VMMLIB_THROW_EXCEPTIONS
#  ifdef VMMLIB_DONT_FORCE_ALIGNMENT
#    define VMMLIB_ALIGN( var ) var
#  else
#    ifdef __GNUC__
#      define VMMLIB_ALIGN( var ) var __attribute__((aligned(16)))
#    elif defined WIN32
#      define VMMLIB_ALIGN( var ) __declspec (align (16)) var
#    else
#      error "Alignment macro undefined"
#    endif
#  endif
#endif

This offers different settings, depending on what system it's building for.

Regardless, thanks. Can't believe I got confused over a member access!

+3  A: 

Ultimately, myVector.array refers to the array variable in the class, and variables don't need the function-calling notation ().

BTW / all-capital identifiers should only be used for preprocessor macros (as they are here). In this case, the macro VMMLIB_ALIGN must be being used to make it easier to later "enchance" the code generated for and alongside the array variable (e.g. prefixing it with static, extern, const, volatile or something compiler-specific) and/or adding some associated functionality such as get/set/search/clear/serialise functions that work on the array.

In general - when you're not sure what the macro is doing, you can get more insight by running the compiler with a command-line switch requesting preprocessor output (in GNU g++, the switch is -E)... then you'll be able to see the actual source code that the C++ compiler proper deals with.

EDIT - few thoughts re your comment, but too long to include in a comment of my own...

C++ classes are private until another access specifier is provided (but in practice the public interface is normally put first so the programmer still must remember to explicitly use private). structs are public by default. So, data is effectively exposed by default in the most common coding style. And, it doesn't need functional-call semantics to access it. Objective-C may well be better at this... your comment implies you use functional call notation for data members and functions, which is hidden by default? It's so good to have a common notation! In C++, the difficult case is where you have something like...

struct Point
{
    double x, y;
};

...

// client usage:
this_point.x += 3 - that_point.y;

...then want to change to...

struct Point
{
    double angle, distance;
};

...you'd need some pretty fancy and verbose manually-coded and not terribly efficient proxy objects x and y to allow the old client code to keep working unmodified while calculating x and y on the fly, and updating angle and distance as necessary. A unified notation is wonderful - allowing implementation to vary without changes to client source code (though clients would need to recompile).

Tony
ok, I just assumed that the underlying array of the vector would be hidden or something. Buh... Objective-C is getting to me.
Stephen Furlani
To answer your additional comments, in Objective-C all members are private, and use getters/setters because of the default ref-count memory management. `[object setMember: newValue];` or for a get `int myNum = [object member];` I was looking to see what kind of syntax in C++ didn't require the `()` because I haven't accessed a public member in forever! Plus, templates are tricky for me to read.
Stephen Furlani
+1  A: 

array is not a method, it's an array of type T of size M.

Andrew Cooper
+2  A: 

maybe I'm oversimplying, but if you look at the #define macro it just writes the variable into the class.

So you have

class vector
{
...
  T array[ M ];
};

after the expansion. So it's just a public variable on your class.

Tim Hoolihan
wow. I thought this would be private... but I guess not.
Stephen Furlani
+1  A: 

First, for the record, templates have nothing to do with this. There is no special interaction between the macro and the fact that your class is a template.

Second, going by the name of the macro, I'd guess it is meant to ensure alignment of a variable.

That is, to get an aligned instance x of a type X, you'd use VMMLIB_ALIGN(X x);

In practice, the macro does nothing at all. It simply inserts its argument, so the above results in the code X x; and nothing else.

However, it may be that the macro is defined differently depending on the hardware platform (since alignment requirements may vary between platforms), or over time (use a dummy placeholder implementation like this early on, and then replace it with the "real" implementation later)

However, it does seem pointless since the compiler already ensures natural alignment for all variables.

jalf