What's the -Wsomething flag for 'instance method not found' warnings? - objective-c

I recently had a case where someone added a parameter to an init method and broke another project that shared the code. Since it's only a warning, nobody realized the app was broken, so I'm trying to turn only this warning into an error:
warning: instance method '-someMethod' not found (return type defaults to 'id')
I've found that you can pass -Werror=foo in Other C Flags to the compiler in Xcode to turn a warning into the error, but I can't seem to find what 'foo' should be. I've tried 'undeclared-selectors' but that only catches #selector cases. I've tried -Werror-implicit-function-declaration but that doesn't seem to catch that case either.
I tried 'inst-method-not-found' and 'instance-method-not-found' after finding 'warn_inst_method_not_found' during a casual search of the huge clang source code.
Help ... ?
Update:
Here's an example you can compile (e.g. in CodeRunner) to see the warning: https://gist.github.com/4045701

The option you're looking for is -Werror=objc-method-access. Clang explicitly tells you this right in the warning message, if you download and compile that gist you posted:
% clang test.m -c
test.m:13:21: warning: instance method '-initWithNum:' not found (return type
defaults to 'id') [-Wobjc-method-access]
...theObj = [[MyClass alloc] initWithNum: [NSNumber numberWithInt: 15]];
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
% clang test.m -Werror=objc-method-access -c // ta-da!
But in real-world situations I agree with all the commenters above: You should fix or suppress all compiler warnings. Your build should build cleanly all the time. Otherwise, as you so rightly observed, you won't be able to distinguish real bugs from "the usual spam".
FWIW, here's the version of Clang I'm using:
$ clang --version
clang version 3.2 (http://llvm.org/git/llvm 1503aba4a036f5394c7983417bc1e64613b2fc77)
Target: x86_64-apple-darwin12.2.0
Thread model: posix

Related

How can I define an executable that has different compiler command-line arguments?

I have a C++ project and I want to test the compatibility of library headers with different compiler versions. I have a simple source file (that includes said headers) and I want to change the compiler argument to std=gnu++11 for this one target. How do I do that?
executable('old_compiler_test', ['octest.cxx']
# override ARGS here ??? how
)
Note that I have
add_global_arguments(
['-std=gnu++17',
....
rather than the dedicated option for this, in spite of the warning to prefer the special option, because the special option simply doesn't work. (Why is a question I've never tracked down)
update
To clarify: I'm not trying to make additional configurations in the same way that debug and release are configurations. I want a different compiler argument to be applied to a single target within the configuration.
From the Meson documentation, you can use the argument <languagename>_args to pass additional compiler arguments. In your case, since you use C++, it would give something like
executable('old_compiler_test', ['octest.cxx'],
cpp_args: ['std=gnu++11']
)
However the documentation also specify that there are no way to disable an argument added by add_global_argument(), so you will end up with both -std=gnu++17 and -std=gnu++11 passed to the compiler. I don't know how your compiler will behave, but I tried to pass both arguments to GCC 10.2 and it uses c++17 (not what you want).
Workaround
It seems that if you define the C++ version in the project() statement, Meson will removes it if an other version is specified in compiler arguments, giving the behaviour you expect.
Here is the sample I used:
meson.build
project('project-name', 'cpp',
default_options: ['cpp_std=c++17']
)
executable('old_compiler_test', ['octest.cxx'],
cpp_args: ['-std=gnu++11']
)
octest.cxx
#include <iostream>
int main() {
std::cout << __cplusplus << std::endl;
}
After compilation, running the executable will print 201103, which means that the compiler used c++11 as desired.

How to suppress warnings for 'void*' to 'foo*' conversions (reduced from errors by -fpermissive)

I'm trying to compile some c code with g++ (yes, on purpose). I'm getting errors like (for example):
error: invalid conversion from 'void*' to 'unsigned char*' [-fpermissive]
adding -fpermissive to the compilation options gets me:
error: invalid conversion from 'void*' to 'unsigned char*' [-Werror=permissive]
which seems to be a error because of -Werror, however adding -Wno-error=permissive -Wno-permissive results in:
error: -Werror=permissive: no option -Wpermissive
error: unrecognized command line option "-Wno-permissive" [-Werror]
How do I disable warnings (globaly) for conversions from void* to other pointer types?
You cannot "disable warnings for conversions from void* to other pointer types" because this is not a warning - it is a syntax error.
What's happening here is that you are using -fpermissive which downgrades some errors - including this one - to warnings, and therefore allows you to compile some non-conforming code (obviously many types of syntax errors, such as missing braces, cannot be downgraded to warnings since the compiler cannot know how to fix them to turn them into understandable code).
Then, you are also using -Werror which upgrades all warnings to errors, including the "warnings" that -fpermissive has turned your error into.
-Wno-error is used only to negate -Werror, i.e. it causes -Werror to treat all warnings as errors except the warnings specified with -Wno-error, which remain as warnings. As the -W flag suggests, both these flags work with warnings, so they can't do anything with this particular issue, since what you have here is an error. There is no "warning" for this kind of invalid conversion that you can switch off and on with -Werror because it's not a real warning - it's an error that -fpermissive is merely causing to be treated as a warning.
You can compile your non-comforming code, in this case, by using -fpermissive and not using -Werror. This will still give you a warning, but like all warnings, it won't prevent successful compilation. If you are deliberately trying to compile non-conforming code, then using -Werror makes no sense, because you know your code contains errors and will therefore result in warnings, even with -fpermissive, so specifying -Werror is equivalent to saying "please do not compile my non-conforming code, even though I've just asked you to."
The furthest you can go to get g++ to suppress warnings is to use -fsyntax-only which will check for syntax errors and nothing else, but since what you have here is a syntax error, that won't help you, and the best you can do is have that turned into a warning by -fpermissive.
How do I disable warnings (globaly) for conversions from void* to
other pointer types?
Well it might require direct interaction with compiler's code. This is probably not what you want. You want to fix your code. First, these are not warnings but errors. You need to cast void* as you can not convert a void* to anything without casting it first (it is possible in C however which is less type safe as C++ is).
For example you would need to do
void* buffer = operator new(100);
unsigned char* etherhead = static_cast<unsigned char*>(buffer);
^
cast
If you want a dynamically allocated buffer of 100 unsigned char then you are better off doing this
unsigned char* p = new unsigned char[100];
and avoiding the cast.
void pointers

Code does not compile for extra large implementation file

The compiler exits by throwing following error.
/var/folders/2t/jkh9ngsn6f9bnmz8l0mz0zm80000gs/T/xsdLocal20-ZhAiH9.s:1895977:branch out of range
clang: error: assembler command failed with exit code 1 (use -v to see invocation)
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang failed with exit code 1
The file has 98341 number of lines.
using compiler Apple LLVM 3.1
The code builds for simulator but not for iOS device
Save the original file.
Comment out out #implementation after another, til the file compiles properly. Npw you know the class that is giving you the problem.
Then take the very biggest method, adding '#if 0' around the code, and at the top before the '#if 0', return a proper value - YES, NO, nil, whatever so the file will compile.
Compile. Do you still get the problem? Then comment out the next largest method, or just do the methods sequentially, or use a binary search technique (ie comment out one half of the methods, then the other half, to drill down on the culprit.
Once you find the problem method, you will need to refactor it into two or more methods, which probably can be private to the class, so your public interface does not change.

Xcode 4: "error: unknown type name 'BOOL'; did you mean 'BOOL'?"

I have a project which worked great under Xcode 3.2.x. Under Xcode 4.2, I'm getting the following error when compiling:
"error: unknown type name 'BOOL'; did you mean 'BOOL'?"
I can right click on the offending BOOL and Xcode will jump to Apple's definition. BOOL is defined in <objc/objc.h>, so I included it in my source file (despite the fact that I'm using precompiled headers with UIKit.h and Foundation.h). Still no joy - the compile error persists.
Any ideas for Xcode 4 work arounds would be appreciated. Google is offering 0 hits.
EDIT: added the offending code to remove any ambiguity.
// AppConstants.h
typedef enum { ThreadPriorityLow = NSOperationQueuePriorityLow, ThreadPriorityNormal = NSOperationQueuePriorityNormal,
ThreadPriorityHigh = NSOperationQueuePriorityHigh, ThreadPriorityDefault = ThreadPriorityNormal } ThreadPriority;
static inline BOOL IsValidThreadPriority(ThreadPriority priority)
{
return priority == ThreadPriorityLow || priority == ThreadPriorityNormal || priority == ThreadPriorityHigh;
}
EDIT: after looking at the source under Emacs and HexFiend for illegal characters and finding none (source is 8-bit clean), I'm inclined to believe this is due to some kind of bug on Apple's part.
A wild guess is a special character that appeared on your line, you were probably using some special character encoding in XCode 3 and opening the file in XCode 4 triggers this error.
To see if this answer is correct I would recommend you cat or vim the file in your terminal and see if some wild characters are located at this specific line.
Let us know if this works
It was broken Apple software.
Apple disregarded my 3.2.6 projects settings and decided to use the LLVM 3.0 suite rather than GCC 4.2. Previously (under Xcode 3.2.6), I had specifically set the project to use GCC due to my extensive use of GCC warnings and flags.
After I changed 'Build Settings' -> 'Compile for C/C++/Objective' back to GCC 4.2, it worked.
Apple Radar 10278815 reported, and LLVM Bug 11126 reported. Hopefully Apple will fix it before Xcode 5.

what is this error message complaining about? and how to resolve it?

try to apply a patch and compile received warning message:
<some_file>: In function '-[XXXXX saveAndCreate:]':
<some_file>:262: warning: 'NSString' may not respond to '-stringByReplacingOccurrencesOfString:withString:'
<some_file>:262: warning: (Messages without a matching method signature
<some_file>:262: warning: will be assumed to return 'id' and accept
<some_file>:262: warning: '...' as arguments.)
distcc[6493] ERROR: compile (null) on localhost failed
which is complaining about this code,
[clientHost findAvailableIn:
[clientHost defaultVMPath]
baseName:
[displayName stringByAppendingPathExtension:PL_BUNDLE_EXTENSION]
nameFormat:[[displayName
stringByReplacingOccurrencesOfString:#"%"
withString:#"%%"]
stringByAppendingString:#" %u.xxxx"]
startIndex:2
contextInfo:contextInfo];
and here is part of the compile command:
lin32/gcc-5363-1/bin/i686-apple-darwin8-gcc -mmacosx-version-min=10.4 -arch i386 -march=pentium-m -mtune=prescott -Werror -Wall -Wno-trigraphs -Wreturn-type -Wunused-variable -pipe -O2 -g3 -gfull -Wno-pointer-sign -x objective-c -fobjc-exceptions -fpascal-strings -fmessage-length=0
googled the warning and tried the method here , but still got warning message alike.
i am ignorant in Mac development, spare me if this is something obvious (and i donnot know if the information provide above is surfficent, let me know what else needed to provide). thanx.
edit:
1) extend the code block.
2) correct the warning message.
The warning is referencing a different line the one you cited. The message you use is called stringByReplacingOccurrencesOfString:withString: which is fine on NSString. However the method replaceOccurrencesOfString:withString attempts to change the receiver. NSString is immutable and can therefore not be changed. If you want to use that method send it to a NSMutableString object.
Are you importing <Foundation/Foundation.h>? What is very surprising is that you would receive this warning, but no warning on -stringByAppendingPathExtension. Is this really the only warning you're receiving?
I recommend breaking up the code to create some temporary variables. You're doing so many nested method calls, it makes it very hard to be certain where your errors are. The compiler will optimize out most temporary variables, so there's no reason to avoid them when it makes the code clearer.