Using the C preprocessor to determine current scope? - scope

I am developing an application in C / Objective-C (No C++ please, I already have a solution there), and I came across an interesting use case.
Because clang does not support nested functions, my original approach will not work:
#define CREATE_STATIC_VAR(Type, Name, Dflt) static Type Name; __attribute__((constructor)) void static_ ## Type ## _ ## Name ## _init_var(void) { /* loading code here */ }
This code would compile fine with GCC, but because clang doesn't support nested functions, I get a compile error:
Expected ';' at end of declaration.
So, I found a solution that works for Clang on variables inside a function:
#define CREATE_STATIC_VAR_LOCAL(Type, Name, Dflt) static Type Name; ^{ /* loading code here */ }(); // anonymous block usage
However, I was wondering if there was a way to leverage macro concatenation to choose the appropriate one for the situation, something like:
#define CREATE_STATIC_VAR_GLOBAL(Type, Name, Dflt) static Type Name; __attribute__((constructor)) void static_ ## Type ## _ ## Name ## _init_var(void) { /* loading code here */ }
#define CREATE_STATIC_VAR_LOCAL(Type, Name, Dflt) static Type Name; ^{ /* loading code here */ }(); // anonymous block usage
#define SCOPE_CHOOSER LOCAL || GLOBAL
#define CREATE_STATIC_VAR(Type, Name, DFLT) CREATE_STATIC_VAR_ ## SCOPE_CHOOSER(Type, Name, Dflt)
Obviously, the ending implementation doesn't have to be exactly that, but something similar will suffice.
I have attempted to use __builtin_constant_p with __func__, but because __func__ is not a compile-time constant, that wasn't working.
I have also tried to use __builtin_choose_expr, but that doesn't appear to work at the global scope.
Is there something else I am missing in the docs? Seems like this should be something fairly easy to do, and yet, I cannot seem to figure it out.
Note: I am aware that I could simply type CREATE_STATIC_VAR_GLOBAL or CREATE_STATIC_VAR_LOCAL instead of messing with macro concatenation, but this is me attempting to push the limits of the compiler. I am also aware that I could use C++ and get this over with right away, but that's not my goal here.

#define SCOPE_CHOOSER LOCAL || GLOBAL
#define CREATE_STATIC_VAR(Type, Name, DFLT) CREATE_STATIC_VAR_ ## SCOPE_CHOOSER(Type, Name, Dflt)
The biggest difficulty here is that the C preprocessor works by textual substitution, so even if you figured out how to get SCOPE_CHOOSER to do what you want, you'd end up with a macro expansion that looked something like
CREATE_STATIC_VAR_LOCAL || GLOBAL(Type, Name, Dflt);
There's no way to get the preprocessor to "constant-fold" macro expansions during substitution; the only time things are "folded" is when they appear in #if expressions. So your only hope (modulo slight handwaving) is to find a single construction that will work both inside and outside of a function.
Can you explain more about the ultimate goal here? I don't think you can load the variable's initial value with __attribute__((constructor)), but maybe there's a way to load the initial value the first time the function body is entered... or register all the addresses of these variables into a global list at compile-time and have a single __attribute__((constructor)) function that traverses that list... or some mishmash of those approaches. I don't have any specific ideas in mind, but maybe if you give more information something will emerge.
EDIT: I don't think this helps you either, since it's not a preprocessor trick, but here is a constant-expression that will evaluate to 0 at function scope and 1 at global scope.
#define AT_GLOBAL_SCOPE __builtin_types_compatible_p(const char (*)[1], __typeof__(&__func__))
However, notice that I said "evaluate" and not "expand". These constructs are compile-time, not preprocessing-time.

Inspired by the #Qxuuplusone answer.
The suggested macro for AT_GLOBAL_SCOPE does indeed work (in GCC), but causes a compiler warning (and I am pretty sure it cannot be silenced by Diagnostic Pragma because it's created by pedwarn with a test here).
Unless you turn on -w you will always see these warnings and have, in the back of your mind, a horrible feeling that you probably shouldn't be doing whatever it is that you are doing.
Fortunately, there is a solution that can silence these lingering doubts.
In the Other Builtins section, there is __builtin_FUNCTION with this very interesting description (emphasis mine):
This function is the equivalent of the __FUNCTION__ symbol and returns an address constant pointing to the name of the function from which the built-in was invoked, or the empty string if the invocation is not at function scope.
It turns out, at least in version 8.3 of GCC, you can do this:
#define AT_GLOBAL_SCOPE (__builtin_FUNCTION()[0] == '\0')
This still probably won't answer the original question, but until GCC decides this too will cause a warning (it kind of seems like it's intentionally designed not to though), it lets me continue doing questionable things using macros without anything to warn me that it's a bad idea.

Related

Variable argument list with different types in MetaTrader5

I have some mql5 code which I want to print debug messages if the DEBUG macro is set. I would like to use a different function (DebugPrint for that matter) for those debug messages. My first attempt was to create a regular function, but variable arguments don't seem to work. I then tried to use the precompiler to remove the DebugPrint-calls based on this answer, however the compiler's pre-processor doesn't seem to understand the variable argument list either. This is the code I tried:
#ifdef DEBUG
#define DebugPrint(...)
#else
#define DebugPrint(...) Print(__VA_ARGS__)
#endif
Any ideas on how to achieve what I'm trying to do?
My few cents on MQL4/5:
Preprocessor directives:
while the revised New-MQL4.56789 compiler has opened some new, more complex constructs for #define preprocessor directives syntax, I have almost always burnt my fingers when trying to use them in production code.
Variadic arguments:
MQL4/5 is a strong-typed, compiled language and as such does not provide means for variadic functions. With some recent syntax aids, coming from ( OOP ) Class-based function ( method ) call-interface overrides and maybe using some advanced abstractions from so called function-template-s, there are chances to create some sort of syntax-support for your #define-dependent behaviour.
Function Overloading,template-sandtypename-dependent actions:
Whereas these techniques have brought even more "New" compiler features into the MQL4/5 software domain, the additional levels of complexity do not justify the efforts, given the resulting principles are restricted from being usable in cases where their use is restricted from export, virtual or #import constructs.
So how to make this work?
Well, for the sake of the rapid & iterative development needs, one may resort to an "almost-variadic" PrintFormat( DEBUG_MASK, ..., ..., ... ); using a context-full (known) matching set of attributes against a static, context-specific #define-ed DEBUG_MASK. Nested construction of FormatString( MASK_A, par1, par2[, FormatString( MASK_B, par3, par4[, FormatString( ... )[, ... ] )[, ... ]) are left for one's own kind imagination.

Is it possible / easy to include some mruby in a nim application?

I'm currently trying to learn Nim (it's going slowly - can't devote much time to it). On the other hand, in the interests of getting some working code, I'd like to prototype out sections of a Nim app I'm working on in ruby.
Since mruby allows embedding a ruby subset in a C app, and since nim allows compiling arbitrary C code into functions, it feels like this should be relatively straightforward. Has anybody done this?
I'm particularly looking for ways of using Nim's funky macro features to break out into inline ruby code. I'm going to try myself, but I figure someone is bound to have tried it and /or come up with more elegant solutions than I can in my current state of learning :)
https://github.com/micklat/NimBorg
This is a project with a somewhat similar goal. It targets python and lua at the moment, but using the same techniques to interface with Ruby shouldn't be too hard.
There are several features in Nim that help in interfacing with a foreign language in a fluent way:
1) Calling Ruby from Nim using Nim's dot operators
These are a bit like method_missing in Ruby.
You can define a type like RubyValue in Nim, which will have dot operators that will translate any expression like foo.bar or foo.bar(baz) to the appropriate Ruby method call. The arguments can be passed to a generic function like toRubyValue that can be overloaded for various Nim and C types to automatically convert them to the right Ruby type.
2) Calling Nim from Ruby
In most scripting languages, there is a way to register a foreign type, often described in a particular data structure that has to be populated once per exported type. You can use a bit of generic programming and Nim's .global. vars to automatically create and cache the required data structure for each type that was passed to Ruby through the dot operators. There will be a generic proc like getRubyTypeDesc(T: typedesc) that may rely on typeinfo, typetraits or some overloaded procs supplied by user, defining what has to be exported for the type.
Now, if you really want to rely on mruby (because you have experience with it for example), you can look into using the .emit. pragma to directly output pieces of mruby code. You can then ask the Nim compiler to generate only source code, which you will compile in a second step or you can just change the compiler executable, which Nim will call when compiling the project (this is explained in the same section linked above).
Here's what I've discovered so far.
Fetching the return value from an mruby execution is not as easy as I thought. That said, after much trial and error, this is the simplest way I've found to get some mruby code to execute:
const mrb_cc_flags = "-v -I/mruby_1.2.0_path/include/ -L/mruby_1.2.0_path/build/host/lib/"
const mrb_linker_flags = "-v"
const mrb_obj = "/mruby_1.2.0_path/build/host/lib/libmruby.a"
{. passC: mrb_cc_flags, passL: mrb_linker_flags, link: mrb_obj .}
{.emit: """
#include <mruby.h>
#include <mruby/string.h>
""".}
proc ruby_raw(str:cstring):cstring =
{.emit: """
mrb_state *mrb = mrb_open();
if (!mrb) { printf("ERROR: couldn't init mruby\n"); exit(0); }
mrb_load_string(mrb, `str`);
`result` = mrb_str_to_cstr(mrb, mrb_funcall(mrb, mrb_top_self(mrb), "test_func", 0));
mrb_close(mrb);
""".}
proc ruby*(str:string):string =
echo ruby_raw("def test_func\n" & str & "\nend")
"done"
let resp = ruby """
puts 'this was a puts from within ruby'
"this is the response"
"""
echo(resp)
I'm pretty sure that you should be able to omit some of the compiler flags at the start of the file in a well configured environment, e.g. by setting LD_LIBRARY_PATH correctly (not least because that would make the code more portable)
Some of the issues I've encountered so far:
I'm forced to use mrb_funcall because, for some reason, clang seems to think that the mrb_load_string function returns an int, despite all the c code I can find and the documentation and several people online saying otherwise:
error: initializing 'mrb_value' (aka 'struct mrb_value') with an expression of incompatible type 'int'
mrb_value mrb_out = mrb_load_string(mrb, str);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
The mruby/string.h header is needed for mrb_str_to_cstr, otherwise you get a segfault. RSTRING_PTR seems to work fine also (which at least gives a sensible error without string.h), but if you write it as a one-liner as above, it will execute the function twice.
I'm going to keep going, write some slightly more idiomatic nim, but this has done what I needed for now.

Why do I have to specify an ExtPgm parameter for the Main Procedure?

My program, PKGDAYMONR has the control option:
ctl-opt Main( CheckDailyPackages )
The CheckDailyPackages procedure has the following PI:
dcl-pi *n ExtPgm( 'PGMNAME' );
As you can see the ExtPgm parameter is not the name of the program. In fact, it’s what came over in the template source and I forgot to change it. Despite the wrong name in ExtPgm, the program runs without a problem.
If I remove that parameter and leave the keyword as just ExtPgm, I get the following message:
RNF3573: A parameter is required for the EXTPGM keyword when the
procedure name is longer than 10.
If I drop ExtPgm from the Procedure Interface altogether, it also complains:
RNF3834: EXTPGM must be specified on the prototype for the MAIN()
procedure.
So why is it that I have to specify a parameter if it doesn't matter what value I enter?
O/S level: IBM i 7.2
Probably worth pursuing as a defect with the service provider; presumably for most, that would be IBM rather than a third-party, as they would have to contact IBM anyhow, given the perceived issue is clearly with their compiler. Beyond that, as my "Answer", I offer some thoughts:
IMO, and in apparent agreement with the OP, naming the ExtPgm seems pointless in the given scenario. I think the compiler is confused while trying to enforce some requirements in validations of the implicitly generated Prototype for the linear-main for which only a Procedure Interface is supplied; i.e. enforcing requirements that are appropriate for an explicit Prototype, but requirements that could be overlooked [thus are no longer requirements] in the given scenario.? I am suggesting that while the RNF3573 would seem appropriate for diagnosing EXTPGM specifications of an explicit Prototype, IMO that same effect is inappropriate [i.e. the validation should not be performed] for an implicit prototype that was generated by the compiler.
FWiW: Was the fixed-format equivalent of that free-form code tested, to see if the same or a different error was the effect? The following source code currently includes the EXTPGM specification with 'PGMNAME' as the argument [i.e. supplying any bogus value of 10-byte naming to supplicate the compiler, just as is being done in the scenario of the OP, solely to effect a successful compile], but could be compiled with the other variations with changes to the source, mimicking what was done with free-form variations, to test if the same\consistent validations and errors are the effect:
- just EXTPGM keyword coded (w/out argument); is RNF3573 the effect?
- the EXTPGM keyword could be omitted; is RNF3834 the effect?
- the D-spec removed entirely (if there are no parameters defined); ¿that was not one of the variations noted in the OP as being tried, so... the effect?
H MAIN(CheckDailyPackages)
*--------------------------------------------------
* Program name: CheckDailyPackages (PGMNAME)
*--------------------------------------------------
P CheckDailyPackages...
P B
D PI EXTPGM('PGMNAME')
/free
// Work is done here
/end-free
P CheckDailyPackages...
P E
I got a response from IBM and essentially Biswa was on to something, it simply wasn't clear (in my opinion) about the answer.
Essentially the EXTPGM is required on long Main procedure names in order to support recursive program calls.
This is the response I received from IBM explaining the reason for the scenario:
The incorrect EXTPGM would only matter if there was a call to the main
procedure (the program) within the module.
When the compiler processes the procedure interface, it doesn't know
whether there might be a call that appears later in the module.
EXTPGM keyword is used to define the external name of the program which you want to prototype. If you mention the EXTPGM then the program will be called dynamically.
Let us take an example in order to explain your query.
PGMA
D cmdExc PR ExtPgm('QSYS/QCMDEXC')
D 200A const
D 15P05 const
c callp cmdExc('CLRPFM LIB1/PF1':200)
C Eval *INLR = *ON
In the above example CmdExc used for the dynamic call to QSYS/QCMDEXC.
When we use the same program name as the EXTPGM parameter it acts as an entry point to the program when called from other programs or procedure.
But in any case when we mention any name as the sample parameter the EXTPGM will not give any error in compilation, but it gives the error during run time as it tries to resolve the name during run time.

What is the usage of Nested comments in some programming languages?

Why nested comments use by some programming languages such as MATLAB ,I just want to know usage of this kind comments in a program and what are the advantages we can gain by using this nested comments ?
The answer is nested comments allows commented-out code that contains comments itself
example in C++ has block comments delimited by /../ that can span multiple lines and line comments delimited by //.
Usually, coding standards for a particular project or program have rules about which comment style to use when; a common convention is to use block comments (/* */) for method and class documentation, and inline comments (//) for remarks inside method bodies and such, e.g.:
/**
* Helper class to store Foo objects inside a bar.
*/
public class Foobar {
/**
* Stores a Foo in this Foobar's bar, unless the bar already contains
* an equivalent Foo.
* Returns the number of Foos added (always 0 or 1).
*/
public int storeFoo(Foo foo) {
// Don't add a foo we already have!
if (this.bar.contains(foo)) {
return 0;
}
// OK, we don't have this foo yet, so we'll add it.
this.bar.append(foo);
return 1;
}
}
If someone wants to temporarily disable entire methods or classes in the above program.It's very helpful, if that language allows nested comments.
You can use comments...:
to temporally disable some lines of code.
as titles for sections.
to comment each line.
to add some notations or comments on other comments.
to send macro orders.
And you can mix all of them. That's why we need different ways to mark comments and create nested comments.
Good old Turbo Pascal aka Borland Pascal allows multi-line comments either with curly braces { } or with parenthesis star (* *), which nest independently of one another even though multi-line comments in the same style do not nest.
A good workaround from my old work place was use of typical brace { } comments for all informational comments and specialized use of the less common parenthesis star (* *) only to comment out code. Marking the middle lines of commented out code with something like ** is still a decent idea, and macros can be used to achieve this in programmer editors
function ComputeCost(var x : longint);
{ Wide version: Apply discounts to raw price.}
(* CODE GRAVEYARD!
** function ComputeCost(var x : integer);
** {Apply discounts to raw price.}
*)
Minimalists will always discount the need for nested comments by saying that C style languages allow constructs like #ifdef SOMETHING or the elegantly short #if 0 to disable code. True minimalists want old code removed completely and say version control takes the place of keeping old code. A good counter is that commented out code together with programmer editors with folding support, e.g. Vim, allows visually stepping over dead code while keeping it for reference.
I feel that nested comments are not necessary! In general a comment is omitted by the compiler so comments serve a main purpose for indicating the programmer what he had done or a new programmer to know the flow of the program..why unnecessarily nest comments..just an indication that can be without nesting.. eg:
for(;;)
{
if()
{
}
}/* a loop with an if condition*/
**need not be as**
/*a loop/*if condition*/for n times*/

how to specify attribute of GNU C?

In GUN C manual, 6.30 Declaring Attributes of Functions, it states:
You may also specify attributes with __ preceding and following each keyword. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use __noreturn__ instead of noreturn.
Does this mean that user can specify customized attributes? Or what else? I'm definitely confused, could anyone help, or give me some samples?
What it's saying is that a header file might have done:
#define noreturn 3
If you then try to declare a function as:
void fatal () __attribute__ ((noreturn));
it will be processed as if you'd written:
void fatal () __attribute__ ((3));
which is not what you want. So you can write instead:
void fatal () __attribute__ ((__noreturn__));
This is safe because users are not allowed to define macros with names beginning with two underscores, these names are reserved for the implementation. See What are the rules about using an underscore in a C++ identifier?

Resources