In C/C++ we've had
#ifdef _DEBUG
...
#endif
In C# we've got
#if DEBUG
...
#endif
and
[Conditional("DEBUG")]
I don't expect anything as fancy as an attribute based way of dealing with debug only code but would like to know if there's a manifest constant kind of thing or any other way of making code only present in a debug build. For instance I'm doing the following in Lua at the moment:
if not type(parameters.callback) == 'function' then
error('The "callback" parameter is not a function, or missing (nil).');
end
if not type(parameters.times) == 'number' then
error('The "times" parameter is not a number or missing (nil).');
end
if not type(parameters.interval) == 'number' or not parameters.interval == nil then
error('The "interval" parameter is not a number.');
end
I don't even know if that will run. Totally new to the language.
Given the nature of the function I'm writing, a simple retry function taking the number of attempts to make, an optional interval and a callback as parameters - which I anticipate being used many times throughout the application being written - and that its to be run on a micro controller I feel these checks should not be made in a production release as I'm guessing they could be relatively costly?!?! I'm even doing a type check within a for loop.
Is there already something built into the language to allow for conditional compilation? Or has anyone come up with a neat and clean way of handling this sort of thing? I know I could declare a global variable marking it a debug build and simply put and if block around the above but I thought I'd ask.
Googling has got me nowhere. In fact when I read the sites that talk about Lua I feel like I've stepped back to the mid to late 90's web.
Thanks,
Lee.
EDIT
Or perhaps I just write the method as a C module?!?!
way of making code only present in a debug build
There is no "build" for Lua. It's an interpreted language. Internally it is compiled to byte code, but that's an implementation detail.
However, if you're OK with having a build step, then you can just use a precompiler, exactly as C does. In fact, you can use the same one your your C compiler does, then you're getting the exactly syntax you're already familiar with.
For instance, my old copy of MSVC uses cl /EP <filename> to run filename through the preprocessor and dump the output to stdout. Then you can write:
#ifdef _DEBUG
-- debug Lua code goes here
#endif
The cleanest way would probably be something like
_DEBUG = true
if _DEBUG then
--code
end
The flavour of Lua being used is eLua or Embedded Lua and it does allow pre-compiling scripts to bytecode.
The code is on GitHub so if time permits I'll see about submitting a patch that will allow for true conditional compilation as it's all C under the hood.
In that way everyone benefits. Whether the checks in the original question are costly or not there are often times when you want code in or out depending upon whether you're actively working on it or its being used in a production environment but not the other way around.
And since they support pre-compilation and only target embedded devices with differing levels of performance and memory constraints I wouldn't be surprised if they haven't already implemented support. I'll hop along there and find out next.
Thanks all.
Related
I have something like this in my code that checks for user's license:
// C# code:
#if DEBUG
MakeLicenseValidForever();
#else
CheckLicense();
#endif
Now, I need to know if these directives get saved in my released binary or not. If they do get saved, then a user can make #if DEBUG return true and bypass the checks. I need to know if #if DEBUG is safe.
PS1: Obviously I use release mode for distribution.
PS2: I asked my question here first, but since it's not getting any attention, I ask it here again!
No, preprocessor directives are processed at compile time, namely, the compiler won't compile the section into the resulting binary. It's more like code comments, which are discarded during compilation, you can even put invalid statement there and the compiler won't complain about it.
In general, however, your code would be compiled to intermediate language(IL), which isn't native machine code and be decompiled pretty easily. If you want protection better use some AOT compilation technology or obfuscator.
C# is a language which is compiled into byte code, eg your statements are getting processed during compilation.
Conditional statements, used by compiler, are accessable and compilable only if they are defined. In another words, compiler do not see any other statements and your code is safe
I'm writing a UWP program to detect colors from LEDs, this program runs on a Raspberry Pi 3 with Windows 10 IoT with attached display.
What the program does is take a reference image with the LED turned off, then take a image from the LED turned on.
Both images are converted to the same pixelformat and then are cropped to a smaller size, in which only the LED is shown (both the reference and the lighted LED).
Then those picture parts are converted to grayscale wich is followed by creating a difference picture of the two, so that only pixels that changed from the reference to the lighted LED are shown.
To do so I use the NuGet-Package portable.AForge.imaging. The code is shown below.
LEDBildNeu = LEDBild.Clone(PixelFormat.Format24bppRgb);
ReferenzbildNeu = Referenzbild.Clone(PixelFormat.Format24bppRgb);
Crop cropping = new Crop(new System.Drawing.Rectangle(Convert.ToInt32(x), Convert.ToInt32(y), 100, 100));
CroppedLED = cropping.Apply(LEDBildNeu);
CroppedReferenz = cropping.Apply(ReferenzbildNeu);
Grayscale grayscale = new Grayscale(0.2125, 0.7154, 0.0721);
GrayscaleReferenz = grayscale.Apply(CroppedReferenz);
GrayscaleLED = grayscale.Apply(CroppedLED);
Difference difference = new Difference(GrayscaleReferenz);
Differenzbild = difference.Apply(GrayscaleLED);
This code works fine as long as im in debug mode, all of the functions are working.
However when i change to release mode, i get this error while building:
1>C:\Users\morsch.nuget\packages\microsoft.net.native.compiler\1.7.2\tools\Microsoft.NetNative.targets(697,5): warning : MCG : warning MCG0007: Unresolved P/Invoke method 'ntdll.dll!memcpy' for method 'System.Byte* AForge.SystemTools.memcpy(System.Byte*, System.Byte*, System.Int32)'. Calling this method would throw exception at runtime. Please make sure the P/Invoke either points to a Windows API allowed in UWP applications, or a native DLL that is part of the package. If for some reason your P/Invoke does not satisify those requirements, please use [DllImport(ExactSpelling=true) to indicate that you understand the implications of using non-UWP APIs.
1>C:\Users\morsch.nuget\packages\microsoft.net.native.compiler\1.7.2\tools\Microsoft.NetNative.targets(697,5): warning : MCG : warning MCG0007: Unresolved P/Invoke method 'ntdll.dll!memset' for method 'System.Byte* AForge.SystemTools.memset(System.Byte*, System.Int32, System.Int32)'. Calling this method would throw exception at runtime. Please make sure the P/Invoke either points to a Windows API allowed in UWP applications, or a native DLL that is part of the package. If for some reason your P/Invoke does not satisify those requirements, please use [DllImport(ExactSpelling=true) to indicate that you understand the implications of using non-UWP APIs.
When I run the code in release mode and get to the part where the difference picture is created, I get the exception
System.TypeLoadException: 'Unresolved P/Invoke method 'memcpy!ntdll.dll' from this method. Please look for this method in build warnings for more details.'
According to this 'memset' and 'memcpy' are not supported by UWP. My questions now are:
Why does the program run in debug mode without any problems even when those two entry points are not supported, but as soon as i turn to release mode i get the exceptions?
Is there a workaround for the problem?
I already tried to use
[DllImport("ntdll.dll", EntryPoint = "memset")]
and
[DllImport("ntdll.dll", EntryPoint = "memcpy")]
But either I did it wrong or it just don't work that way.
I know I could just program a workaround in which I check the pixels manually and create a new image, but I wanted to solve that problem if possible.
Finding the correct combination of directives can be a very frustrating and time consuming process. Here is additional information that I received from Microsoft via email, hope this helps:
Helpful links:
https://devblogs.microsoft.com/dotnet/net-native-deep-dive-dynamic-features-in-static-code/
https://learn.microsoft.com/en-us/dotnet/framework/net-native/runtime-directives-rd-xml-configuration-file-reference
https://learn.microsoft.com/en-us/dotnet/framework/net-native/runtime-directive-policy-settings
The analysis we do to get your application ready to be ahead of time compiled is quite extensive. We need to generate code for various generic types, reflection callable wrappers, serialization information, marshalling stubs etc etc. In come cases (as you could imagine) we end up generating more than is strictly necessary due to run away combinatorics. It’s completely possible that some fiddling with our heuristics can get you application to a place where it compiles without any loss of functionality.
Practically speaking, there’s two ways to manipulate the behavior of the compiler. One is through some of our compiler flags available through dropping elements into your csproj. The other is making edits to your applications Properties\Default.rd.xml file.
Compiler flags
There are a wide range of flags available but here’s a couple that may help out:
<ShortcutGenericAnalysis>true</ShortcutGenericAnalysis> - Can help stop runaway analysis of generic types and reduce overall generation requirements.
<UseDotNetNativeSharedAssemblyFrameworkPackage>false</UseDotNetNativeSharedAssemblyFrameworkPackage> - Eliminates one of the linking boundaries the compiler has to fight with. I actually suspect turning this off will make things worse not better but whole program optimizers are hard to reason about but rebuilds are cheap enough to try.
Runtime Directives
There’s lots of reading above but the tl;dr is that this file is read by the compiler and can contain lots of hints about what we want it to do or ignore etc. The overall syntax of the file is also included in the reading above but I don’t think we’re very clear about the one special directive that’s include by default:
<Assembly Name="*Application*" Dynamic="Required All" />
This directive says: “Please save/generate enough information so that all user types can be inspected and created via reflection.” Where ‘user types’ means any type in an assembly that isn’t signed with the .NET key token. So, basically everything that isn’t explicitly .NET Framework. This in leads to lots of bloat but also makes it so most folks don’t ever have to think about these things. In cases where we don’t have enough information, you’ll get runtime exceptions like MissingMetadataException or TypeLoadException or NullReferenceException. Each instance will require a bit of code inspection and fiddling with directives to get patched up. This can be an annoying a fragile process. All that said, the analysis engine is quite sophisticated and you’ll get lots and lots of things ‘for free’ without the special directive or any hassle. It’s entirely possible that your app runs great with just a little bit of tweaking.
Okay, the goal now is to remove this directive but still have a working application. There’s two approaches that have tradeoffs, so I’ll describe both and let you decide if either methodology suits you. Roughly here’s what the two workflows look like:
Start from nothing.
a. Remove the special Application directive
b. Build the app
c. If the build fails, email us, else…
d. Test the app and see if you hit any runtime errors
e. If you do you’ll need to look at the error location and see if adding some directives can help then head back to (b).
f. If you find no errors, you’re done! Hooray!
Start from everything
a. Remove the special Application directive
b. Get a list of the full set of dlls for your project, for example by inspecting here: obj[architecture]\Release\ilc\in
c. For each dll, add a Dynamic directive. They’ll look like: <Assembly Name="ASSEMBLYNAMEWITHOUTEXTENTION" Dynamic="Required All"/>
d. Comment out some subset of these libraries
e. Build the app
f. If the build fails again in RHBIND go to (d)
g. Test the app and see if you hit any runtime errors
h. If you do you’ll need to look at the error location and see if adding some directives can help then head back to (e)
i. If you find no errors, you’re done! Hooray!
I found a solution which worked:
Instead of downloading the portable.AForge package with NuGet i downloaded the portable.AForge from GitHub.
Find the .cs-file called SystemTools.cs (located in AForge/Sources/Core/).
Open it with any .cs editing porgram, now search for all code like
#if !MONO
...
#else
and remove it.
This clears the use of memcpu() or memset() from ntdll.dll.
Save the SystemTools.cs, create the library and add the AForge-Package manually to the application.
After the change it worked without any problems.
I have an application where I used compiler switches to control whether large chunks of code were included or not. Think car with automatic transmission or manual transmission.
Works fine in Debug mode but in Release mode it looks like both Auto Transmission and Manual Transmission are compiled so the car doesn't drive too well...
So am I wrong in trying to get option control functionality out of compiler switches?
More Detail:
My understanding of compiler switches was flawed.
Simple project in comments below.(Not too good at driving StackOverFlow)
To continue the analogy, The (Winform) project was built with manual transmission. It was deployed in debug mode using a setup project. (Mistake).
After some years Auto-transmission was required. (No commonality to give rise to a base class).
The thought was that one day manual transmission may be required again)
Seemed like a compiler switch was a good idea to decide which block of code to use.
Again the Auto-transmission version was deployed in debug mode.
After some more years of running I decided that it should be released. That was when I noticed the problem.
The simple example asked for (thanks) showed me that it wasn't both blocks that were being compiled, just the block in the #else. i.e. Release build regards the switch as off.
So unless I am missing something the answer is self-evident. Don't use compiler switches for deployment options.
I suggest you use composition instead and make use of object-orientation. Have two classes, one for AutoTransmission, and another for ManualTransmission. Each one will derive from a base class Transmission Then you can use either one as you see fit when you create the object that makes use of one of these transmissions.
Then, when you create the object that uses a Transmission, simply instantiate whatever transmission you need. That could be defined in config, or it could be compiler constants. But, I'd recommend against compiler constants because when you perform automatic refactorings blocks of could disabled by #ifdef will not be processed and may not build when you change your compiler options.
In C#, we have 2 modes to build projects : Debug and Release, I wonder if Java has the same thing. I am using IntelliJ IDEA as Java IDE and so far I haven't seen anywhere to configure a build mode like in VS IDE.
javac
-g Generate all debugging info
-g:none Generate no debugging info
-g:{lines,vars,source} Generate only some debugging info
You can choose to include debug symbols in the compiled classes (this is the default) or to not do so. There is not much benefit to not doing that. The jar files will be a little smaller, but the performance benefit is minimal (if any). Without these symbols you no longer get line numbers in stack traces. You also have the option to include additional symbols with local variable names (by default there are only source file names and line numbers).
java
-ea[:<packagename>...|:<classname>]
-enableassertions[:<packagename>...|:<classname>]
enable assertions
You can also enable assertions at run-time (default is off), which is sometimes useful during development and testing. This does have a performance impact (if the code in question did indeed make use of assertions, which I think is uncommon).
Regardless of any of these settings, the JVM always allows you to attach a debugger.
What Java does not have is conditional compilation where completely different code would be compiled based on some external setting. The closest you can get is something like public static final boolean DEBUG_BUILD = true; somewhere in your code and use that in if statements. This will actually make the compiler exclude code that becomes unreachable, but you have to set this constant in the source code.
It is normal practice in Java to release everything is a manner which can be debugged. For some projects requiring obfuscation, they could have a release build, but I have never seen this in 12 years of developing Java.
Things such as assertions and debug messages are usually turned off at runtime for a production instance but can be turned on at any time (even dynamically) if required.
IMHO it is best practice to use the same build in every environment, not just the same source but the same JARs. This gives you the best chance that, if it works in test, it will work in production and if you have a problem in production, you can re-produce it in test.
As so much Java code is written this way, the JIT is very good at optimising dead code which is never called. So much so that IMHO most of the micro-"benchmarks" where Java out performs C++, is when the benchmark doesn't do any thing and the JIT is better at detecting this. IMHO, C++ assumes the developer is smart enough not to write code which doesn't do anything.
You're asking for different kinds of builds to compile in different things I guess. For example to have Debug.WriteLine and Console.WriteLine.
"No, Java doesn't have an exact match for that functionality. You could use aspects, or use an IOC container to inject different implementation classes." stole this from the following question: Conditional Java compilation
(there're other nice answers for you there)
So Jeff Atwood rightly complained about Visual Studio not performing background compilation see: http://www.codinghorror.com/blog/2007/05/c-and-the-compilation-tax.html
The solution from most sources seems to be Reshaper which will incrementally perform background compilation as you write. This leads to their great realtime re-factoring tips and error detection.
But what I don't understand is with R# continually compiling my code, why does it take so long when executing a compilation via VS (i.e. Ctrl + Shift + B or similar). What I mean by this is, if R# has already compiled my code then why would I need a recompilation?
My assumption is of course that R# is not overriding the assemblies in my bin directories but instead holding the compilation results in memory. In which case, is it possible to tell R# to simply override my assemblies when compilation is successful?
I don't know about "rightly complained" - that's an opinion I happen to disagree with:)
However, the VB.NET (and probably Resharper c#) background compilers do not actually compile full assemblies - they cannot! If you think about it, the natural state of your code while you are working is not compilable! Almost every keystroke puts your code in an invalid state. Think of this line:
var x = new Something();
As you type this, from the key "v" to the key ")", your code is "wrong". Or what if you are referencing a method you haven't defined yet? And if this code is in an assembly that another assembly requires, how would you compile that second assembly at all, background or not?
The background compilers get around this by compiling small chunks of your code into multiple transient "assemblies" that are actually just metadata holders - really, they don't care about the actual effects of the code as much as the symbols defined, used, etc. When you finally hit build, the actual full assemblies still need to be built.
So no, I don't believe it's possible because they're not built to do actual full compilation - they are built to check your code and interpret symbols on the fly.
Reshaper which will incrementally perform background compilation as you write
It doesn't, it just parses the source code. The exact same thing Visual Studio already does if you don't have Resharper, that's how it implements IntelliSense, its own refactoring features and commands like GoTo Definition and Find All References. Visual Studio also parses in the background, updating its data while you type. Resharper just implements more bells and whistles with that parsing data.
Going from parsing the code to actually generating the assembly is a pretty major step. The internal format of an assembly is too convoluted to allow this to happen in the background without affecting the responsiveness of the machine.
And the C# compiler is still a large chunk of unmanaged C++ code that is independent from the IDE. An inevitable consequence of having to have the compiler first. It is however a stated goal for the next version of C# to provide compile-on-demand services. Getting true background compilation is a possibility.
I don't really have an answer but I just wanted to say that I have been using Eclipse and Java for 4 months now and I love the automatic compilation. I have a very large java code base and compilation happens constantly as I save code changes. When I hit Run everything is ready to go! It's just awesome. It also deploys to the local web server instance (Tomcat in my case) automatically as I make code changes. All this is setup by default in Eclipse.
I hope Microsoft does something similar with .net in the near future.