I get a "unused static function" warning in Eclipse for code that looks like this:
my.c:
static void myfunc(void) { // This line gives unused warning.
printf("in myfunc()");
}
typedef void(* myfunctyp)(void);
#include "my_generated.h"
my_generated.h:
myfunctyp mylist[] = {
myfunc,
0
}
my_generated.h is a generated code so I cannot just put the array in the .c file.
My Questions are:
How can I tell Eclipse to look into the include file so it can accurately determine that the function is used?
If I cannot get #1, how can I add an indicator in the source code to tell eclipse that this particular warning is okay? I am aware that I can change Window->Preferences->Code Analysis -> Unused Static Function configuration to eliminate the error, but I would like something that "sticks" with the source.
[Edit (Addition)]: The function gets called in the main program like this:
mylist[0]();
If I move mylist[] declaration into the .c file, the warning error does not appear.
Here is one solution:
#define MARKASUSED(x) if (0) { x(); }
static void myfunc(void) {
printf("in myfunc()");
MARKASUSED(myfunc)
}
The 'if (0)' should cause the compiler to remove the code with any kind of optimization on so it would not impact runtime at all.
I don't think this solution is ideal, but it meets my immediate needs.
Related
I have many methods the return value of which is a REFERENCE TO in my libraries. When I open the library, I see a C0222 error in the message window for each of these. If I compile the library, the message goes away. The code compiles and works under both CODESYS and TwinCAT.
Is this just a CODESYS glitch, or is there a reason for that message?
I can confirm that this happens.
Make a PRG or FB with a method that returns a reference to something, the precompiler throws this error:
C0222: Outputs can't be of type REFERENCE TO
However the code compiles fine, and there are no messages in the normal 'Build' section.
(I think that's why the message 'disappears' in your case. The Messages box switches from Precompile to Build when you compile the library.)
I'd suggest listening to the precompiler and avoid returning a reference.
For example:
METHOD Method1 : REFERENCE TO INT
VAR_INST
i : INT;
END_VAR
Method1 REF= i;
Call like this:
result : REFERENCE TO INT;
result REF= Method1();
This code works fine. When you change result you actually change the i variable inside the method. This feels very hacky!
And when you change i from a VAR_INST to a VAR, the code compiles ok, but the reference now points to invalid memory because i goes out of scope when you leave the method.
Edit:
You can use a pragma to disable the error message. Add the following line in every method where you return a reference:
{warning disable C0222} // Disables Precompiler error C0222: Outputs can't be of type REFERENCE TO
METHOD Method2 : REFERENCE TO BOOL
VAR_INPUT
END_VAR
We found a bug in old code which could be easily found if there would be a warning,
The issue was that inner class member was used but not assigned or initialized. Sample code minimized. Problem is that url is always null.
public class Main {
public class Sender {
private String url;
public Sender() {
}
public void send() {
OtherClass.send(url);
}
}
}
In intellij it warns about variable never assigned. In eclipse I didn't find such warning.
The code is more complex and adding a warning at any level will reduce time to find similar bugs.
Is it possible in eclipse to warn in some way if variable is used before assigned/initialized ?
You can use SpotBugs(successor of findbugs) eclipse plugin. Right click on project Spotbugs->find bugs this will find these types of bugs.
I suggest also installing sonarlint plugin which has good static analysis capabilities.
https://marketplace.eclipse.org/content/spotbugs-eclipse-plugin
https://marketplace.eclipse.org/content/sonarlint
I'm working on a change to a library that exposes a new method, but it's only available for a particular architecture. If you call it from an ARM assembly, for instance, I would like a compile-time error instructing you to use a compiler conditional to exclude the call. Is there any way to accomplish this? Something like the following:
public func x86Only() {
#if arch(x86_64)
// Do something here
#else
compiler_fail("x86Only() can only be called from x86_64 architecture")
#end
}
Does something like the (invented) compiler_fail() above exist for Swift?
fatalError() doesn't work as nicely, because it triggers a runtime assertion failure, rather than catching the user error at compile-time.
Since Swift 4.2, you can use #warning to display yellow warnings in Xcode and #error to display red build-time errors.
For example, this code will display a warning with a custom message:
#warning("Fix this code before release!")
These also work inside conditional compiling blocks, which is what you are looking for.
#if os(macOS)
#warning("This library is for iOS only")
#endif
You are looking for something like "compile time assertions"?
Unfortunately, this is not yet implemented. But there's a corresponding thread in the "swift-evolution" list:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/003837.html
In golang, when I import a module, its init() gets executed (before main() I assume?), it is possible some error is generated in this function. How can I capture these errors and handle them in my own code?
Errors in Go are return values, as you may know. As init() does not return anything, the only alternative is to panic() in init if anything goes wrong.
A package that panics on init is arguably not very well designed, although there may be valid use cases for this.
Given the circumstances, recover() is not an option, because init is run before main. So if you can't edit the package in question, then you're out of luck.
This is one of the reasons why panic and recover should be used sparingly, only in situations where literally "panicking" makes sense.
#twotwotwo contributed the following quote from "effective Go" that describes this (for the init case):
if the library truly cannot set itself up, it might be reasonable to panic, so to speak
So: if your init function needs to report an error, then ask yourself if that code really belongs in init or would be better kept somewhere else. If it really has to be init, consider setting an error flag inside of the package and document that any client must check that error.
Yes, package init() functions run before the main() function, see Package initialization in the language specification.
And no, you can't handle errors occurred in package init() functions. Even if you could, that would mean a package your program depends on failed to initialize and you wouldn't know what to expect from it.
Package init() functions have no return values and they can't panic in a meaningful way that was meant to recover from. If an init() function panics, the program terminates.
Since init() functions are not called by you (e.g. from the main() function), you can't recover from there. It is the responsibility of the package itself to handle errors during its initialization, not the users of the package.
One option to signal error happening during an init() is to store the error state in a variable (e.g. exported, or unexported but queryable by an exported function). But this should be used only if it is reasonable to continue, and this is also the task/responsibility of the package itself (to store/report the error) and not the users of the package. You can't do this without the cooperation of the package (you can't "catch" unhandled/unreported errors and panics).
Not directly, but you could using something like this:
package mypkg
var InitErr error
var Foo MyFoo
func init() {
Foo, InitErr = makeInitialisation()
// ...
}
And then in your main:
package main
import "foo/bar/mypkg"
func main() {
if (mypkg.InitErr != nil) {
panic(err)
}
// ...
}
When I compile my iPhone app, xCode gives "duplicate symbol" error for my variables in MyConstants.h
I thought if I used:
#import "MyConstants.h"
it would avoid that?
But I still have the problem.
Added info:
The error occurs during "linking".
(I'm just using xCode's "Build and Go" button.)
I also tried the (unnecessary with #import) #ifndef/def method, too.
Maybe I should just ask this:
If you needed to access a constant in EVERY part of ALL your source code files... what would you put in your .h file? What would you use to include that constant in other parts of your code.
I thought (but I guess it's not) it was simple as:
MyConstants.h> int thisIsGlobal = 123;
(No where am I re-defining thisIsGlobal anywhere in any code.)
And then just "#import MyConstants.h" at the top of each of my other source files.
What you can do is put in your header (MyConstants.h):
extern const int MyConstant;
extern NSString * const MyStringConstant;
And in a source file, include the header above but define the constants (MyConstants.m):
const int MyConstant = 123;
NSString * const MyStringConstant = #"SomeString";
Then, you simply need to include the header in any other source file that uses either of these constants. The header is simply declaring that these constants exist somewhere, so the compiler won't complain, because it's the linker's job to resolve these constant names. The source file that contains your constant definitions gets compiled, and the linker sees that this is where the constants are, and resolves all of the references found in the other source files.
The problem with declaring and defining a constant in a header (that is not declared as static) is that the compiler treats it as an independent global for each file that includes that header. When the linker tries to link all of your compiled sources together it encounters the global name as many times as you have included MyConstants.h.
Two options:
static const int thisIsGlobal = 123;
or
#define thisIsGlobal 123
I use like this, and works: (in a .h outside #interface)
static NSString * const mkLocaleIdentifierUS = #"en_US";
static NSString * const mkLocaleUserSystemSettings = nil;
This is because the symbol name in question (thisIsGlobal) is being emitted into every object file created, where the header containing the declaration for thisIsGlobal is included and visible.
The examples provided by another poster: 'extern const int MyConstant;' is the best way, unless you need the value to be visible, in which case you can use an enum:
int thisIsGlobal = 123; // bad
enum { thisIsGlobal = 123 }; // ok
using static will emit a lot of hidden symbols in a large program -- don't use it. Using a define is scary as well (considering there are safer alternatives available, why not use them?).
I usually put my application constants file in the Xcode project's MyApplication_Prefix.pch file, usually located within the Other Sources group. Any header file included in this pch file will be included from all files in your project.
After adding this include statement, you would then no longer need to include your MyConstants.h file from every file in your project — it will be included automatically.