discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: This NSConstantString thing


From: Markus Hitter
Subject: Re: This NSConstantString thing
Date: Wed, 13 Mar 2002 17:01:48 +0100

Am Dienstag den, 12. März 2002, um 22:36, schrieb Richard Frith-Macdonald:


On Tuesday, March 12, 2002, at 08:59 PM, Markus Hitter wrote:

As you probably know, constant strings are declared/defined in code, but are known to the compiler, too. With Apple's gcc, the compiler explicitely requires a declaration like:

@interface NXConstantString : NSString /* or NSObject */ {
  char *cString;
  unsigned int len;
...
}

But GNUstep declares:

@interface NXConstantString : NSString {
  union {
    unichar     *u;
    unsigned char   *c;
  } _contents;
  unsigned int  _count;
}

which isn't compatible. You notice the additional unicode variable?

It's perfectly compatible, there is no additional variable,
what you are looking at (_contents) is a union ... a single variable.

Here's an excerpt from gcc 3.1's gcc/objc/objc-act.c:

...
/* APPLE LOCAL begin Objective-C++ */
/* Ensure that the ivar list for NSConstantString/NXConstantString
   begins with the following three fields:

   struct STRING_OBJECT_CLASS_NAME
   {
     Object isa;
     char *cString;
     unsigned int length;
   }; */

static int
check_string_class_template ()
{
  tree field_decl = TYPE_FIELDS (constant_string_type);

#define IS_FIELD_OF_TYPE(F, T) \
  (F && TREE_CODE (F) == FIELD_DECL && TREE_CODE (TREE_TYPE (F)) == T)

  if (!IS_FIELD_OF_TYPE (field_decl, POINTER_TYPE))
    return 0;

  field_decl = TREE_CHAIN (field_decl);
  if (!IS_FIELD_OF_TYPE (field_decl, POINTER_TYPE))
    return 0;

  field_decl = TREE_CHAIN (field_decl);
  return IS_FIELD_OF_TYPE (field_decl, INTEGER_TYPE);

#undef IS_FIELD_OF_TYPE
}
/* APPLE LOCAL end Objective-C++ */

... and later:

      if (!check_string_class_template ())
    {
      error ("interface `%s' lacks required ivars",
         IDENTIFIER_POINTER (constant_string_id));
      return error_mark_node;
    }
...

It's the code which checks for some specific ivar layout and it doesn't see a pointer inside a union as a valid pointer. The later is the type of incompatibility I'm speaking of.



Actually the unicode representation is used for the standard unicode concrete subclass of the NSString class. The declaration of NXConstantString is the same as that of the private subclasses because the ivar layout of the two *must* be the same - and declaring them identically (as well as putting comments in the
source) is the clearest way of showing that.

While I can understand you quite well, one could consider it as a cosmetic issue as well. So there are three choices:

1) Get used to live with the cosmetic issue and declare NXConstantString like:

@interface NXConstantString : NSString
{
  /* These (first) two declarations must be byte-compatible with
     @interface GSString : NSString _and_ with the ivar layout required
     by the ObjC++ compiler. */
  unsigned char *_contents;
  unsigned int _count;
}
@end

(already tested, requires about five lines to change in GSString.h)

2) Disable the check for the ivar layout in gcc at the risk of buggier code.

3) Improve the check for the ivar layout at the cost of a more complex compiler.


- place your judgement here -



Cheers,
Markus

- - - - - - - - - - - - - - - - - - -
Dipl. Ing. Markus Hitter
http://www.jump-ing.de/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]