Are “NSString * __unused aString” and “NSString __

2019-05-16 12:55发布

问题:

  1. Are NSString * __unused aString and NSString __unused * aString equivalent, when they are variable declarations?

  2. Are - (void)aMethod:(NSString * __unused)aString and - (void)aMethod:(NSString __unused *)aString equivalent, when they are Objective-C method parameter declarations?

  3. If the answer is "yes", what form should I prefer as correct?

Both forms in both cases seem to work identically when enabling/disabling GCC_WARN_UNUSED_PARAMETER and GCC_WARN_UNUSED_VARIABLE directives.

I didn't find any information to clarify this.


Relevant topics:

__unused Flag Behavior/Usage (GCC with Objective C)

回答1:

There is a difference between the two.

When the attribute, __unused, appears before the star, it decorates the primary type of the entire declaration list. All variables will be "unused":

__unused NSString *foo, *bar; // OK. All variables are unused in the statement. NSString __unused *foo, *bar; // OK

But when placed after the *, it will only apply to the first variable:

NSString * __unused foo, *bar; // Unused variable 'bar'

I prefer NSString * __unused foo; because it seems more clear to me and won't hide the rare case when I declare multiple variables in one statement.

The GCC Attribute Syntax reference mentions it in Section 6.31:

An attribute specifier list may appear immediately before a declarator (other than the first) in a comma-separated list of declarators in a declaration of more than one identifier using a single list of specifiers and qualifiers. Such attribute specifiers apply only to the identifier before whose declarator they appear. For example, in

 __attribute__((noreturn)) void d0 (void),
     __attribute__((format(printf, 1, 2))) d1 (const char *, ...),
      d2 (void) 

the noreturn attribute applies to all the functions declared; the format attribute only applies to d1.



回答2:

There's a third option which behaves similarly: __unused NSString *. This seems more common on Github at least.

For method declarations there is another style similar to the second option in your list:

- (void)aMethod:(NSString *) __unused aString

I read from right-to-left. Going through your list, I read NSString * __unused as an "unused pointer to an NSString instance" and I read NSString __unused * as a "pointer to an unused NSString instance". The former, i.e. #1 in your list, makes the most sense to me.