Q:

When I use Objective-C dot notation to set a subclass member, I get a compiler error

Enrivonment: Mac OS X 10.6.8    Xcode 3.2.3
@interface A : NSObject
@end

@implementation: A
@end

@interface B : A
{
    int b;
}
@property int b;
@end

@implementation B
@synthesize b;
@end

#import "A.h"
#import "B.h"

int main()
{
    A *pa;
    pa = [[B alloc] init];
    pa.b = 3; /*here I get a error: request for member 'b' in something 
                not a structure or union. */

    [pa setB: 3]; // this works.
    return 0;
}

So why is that an error? As I know dot notation and bracket notation do the same thing.

A:

pa is pointer to an instance of class A, which doesn't have a property b.
You need to cast it to a pointer to B:
((B*)pa).b = 3;

This line has no compiler error, but it has warning about an unknown selector (because pa is a pointer to A):
[pa setB: 3];

But in the case of a property, the compiler needs to know what kind of property it is, to be able to generate the appropriate message.

A:

At runtime they do the same, yes, but you are still at compile time.
At compile time, if you use dot notation the compiler doesn't let you get away with something that it thinks might not work. Since you are accessing the object through the base class type A, but the property sits on type B, the compiler complains with an error.
If on the other hand you use bracket notation, the compiler is less adamant and prints a warning only. It concedes that you might know what you are doing :-) but it lets you know that it hasn't seen a method named setB: in the interface of class A.
To get rid of the warning, declare your variable lke this:
id pa;

Using the type id (which translates as "pointer to an object") lets you send any message to an object without a warning, because now the compiler makes no assumptions whatsoever about the object's type. You have arrived in the wonderful world of the fully dynamic language Objective-C :-)

