367

I have Constants NSString, that I want to call like:

[newString isEqualToString:CONSTANT_STRING];

Any wrong code here?

I got this warning:

sending 'const NSString *' to parameter of type 'NSString *' discards qualifiers

How should these be declared?

Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
user4951
  • 32,206
  • 53
  • 172
  • 282

3 Answers3

955

You should declare your constant string as follows:

NSString * const kSomeConstantString = @""; // constant pointer

instead of:

const NSString * kSomeConstantString = @""; // pointer to constant
// equivalent to
NSString const * kSomeConstantString = @"";

The former is a constant pointer to an NSString object, while the latter is a pointer to a constant NSString object.

Using a NSString * const prevents you from reassigning kSomeConstantString to point to a different NSString object.

The method isEqualToString: expects an argument of type NSString *. If you pass a pointer to a constant string (const NSString *), you are passing something different than it expects.

Besides, NSString objects are already immutable, so making them const NSString is meaningless.

Ken
  • 30,811
  • 34
  • 116
  • 155
albertamg
  • 28,492
  • 6
  • 64
  • 71
  • 3
    You said the former is the constant pointer to an NSString object. So that means the pointer is constant. Hence I can't reassign that to another NSString. – user4951 Jul 28 '11 at 04:02
  • 9
    I wish I could give you ten upvotes! Thank you for your understandable and very helpful answer! – Constantino Tsarouhas Jan 02 '12 at 20:17
  • 1
    how in the earth NSString * const is a const pointer to NSString? What's their context free grammar generator? – user4951 Sep 09 '12 at 08:38
  • 7
    @Jim the problem is in you not having learnt C properly, don't blame it on others. The `const` qualifier applies to the term on its left, and it applies to the term on its right only if there's nothing on its left side (e. g. `const char *` and a `char const *` are non-const pointers to const char, but `char *const` is a const pointer to non-const char). –  Oct 11 '12 at 04:29
  • 10
    +1. And +1000 for *"Besides, NSString objects are already immutable, so making them const NSString is meaningless."* – Madbreaks Feb 18 '14 at 20:07
  • Thank you @albertamg. I'd like to add that using #define MACRO string constants in ternary operations produces compiler error, but static NSString * const kMyConst @"CONSTANT_VALUE"; works perfectly well in ternary operations, as such: control.text = (controlActivated==YES) ? mKConst : @"Activate Me"; – ObjectiveTC May 24 '14 at 17:47
  • Nowadays, Xcode sometimes gives a warning if you don't cast the constant string... "(NSString *)". Easy enough. – Paul Brady Sep 03 '14 at 00:23
  • "NSString is already immutable. So making them const is meaningless". Actually, you can reassign them. That's the issue for me. – Patrick Bassut Nov 19 '14 at 09:32
  • @PatrickBassut making the NSString const is meaningless but making the pointer to the NSString const is NOT. That is the point of the answer. – albertamg Nov 19 '14 at 09:52
  • "making the pointer to the NSString const is NOT" meaning that if you use `NSString * const kSomeConstantString` it cannot be reassigned? – Dan Rosenstark Apr 02 '15 at 17:57
  • Also, for static const you should use: *static NSString *const* – OhadM Aug 10 '15 at 14:02
6

just to put all on one place which found on various post on stackoverflow and works for me , #define is bad because you cannot benefit from variable types, basically the compiler replaces all occurrence when compiles (import Constants.h whenever you need) :

//  Constants.h
#import <Foundation/Foundation.h>

@interface Constants : NSObject

extern NSString *APP_STATE_LOGGED_IN;
extern NSString *APP_STATE_LOGGED_OUT;
@end

// Constants.m
#import <Foundation/Foundation.h>
#import "Constants.h"

@implementation Constants

NSString *APP_STATE_LOGGED_IN  = @"APP_STATE_LOGGED_IN";
NSString *APP_STATE_LOGGED_OUT = @"APP_STATE_LOGGED_OUT";
@end
freezing_
  • 984
  • 1
  • 9
  • 13
6

spare few minutes to read this. A goodread on pointers hell on constants and vice-versa.

http://c-faq.com/decl/spiral.anderson.html