Re: [Vala] Define constant at compile time



Hi,

macros are a very useful thing, but of course if you don't use your
brain, they can do a lot of harm. Here's how I see it:

The easiest way is to tell vala to emit the symbols that will then be defined
when compiling the generated C code. That way vala will guard you from name
conflicts and the code will be more readable.

In C, the preprocessor is generally used for two things:
- symbolic constants -- but real constants serve the purpose better and

As Anatol stated in another mail, this is a bad idea to use real
constants, as sometimes you want not to include some code at all during
compilation, basing on a constant value. But the debugcode example is,
I'd call it, a weak example. The strong example would be: the library
that can use different backends for some functionality. Then:

#if BACKEND=UsingSomeLibrary
        some_library_call(foo, bar);
#elsif BACKEND=UsingSomeOtherLibrary
        some_other_library_call(foo, baz, bar);
#endif

Here it's not a matter of optimization or convenience not to include
both calls, and select them at runtime - you have to compile only one
of them, and the other one will simply not compile (as the backend
SomeLibrary does not have some_other_library_call() function).

This currently can be done in Vala with some effort, we have #if,
#else... but:

- sometimes you want to use one switch -D that will enable and disable
  a lot of internal switches. For this, in C you use #ifdef ...
  #define .... In Vala you must rely on a build system to pass all
  switches. I hardly can express in my native language how I HATE such
  solution, so I can't write it in English too... This should be
  possible to enable some defines basing on values of other defines at
  the level of a code, not of a build system. Then one simple file with
  all definitions would be clear and elegant solution.
- doing "const int foo = SOME_DEFINE;" would be a good thing, is it
  possible?

- generic constructs -- but vala does have generics, so you don't need
  those.

Generics do not cover all that macros can do. I can give two examples:

- I need to wrap setjmp. Yes, I need to use setjmp - in debug mode my
  application has a testsuite, and in this testsuite I use
  signal()/setjmp() combination to trap SIGSEGV, just to make the
  testsuite not stop working after first crash. As you may know,
  setjmp() cannot be wrapped in a function (after the function returns
  the jump point would be a trash). It must be wrapped in a macro. If I
  wrap it in an inline function, what guarantee do I have that if the
  compiler reaches inlining limit it will still be inlined? It must be
  wrapped in a macro.
- macros are not type safe. It's bad in most cases, and it's really
  good when you know how to use it. Suppose that I want to wrap any
  function. Let's say that I want to be able to call any function and
  make this call protected by setjmp/signal from crashing with SIGSEGV.
  When using macros in C, I can:

#define TRAPM(a, b) ...

  and use it in a way:

TRAPM(function1, (foo)); // calls function1(foo);
TRAPM(function2, (bar, baz)); // calls function2(bar, baz);

  Quite more powerful than anything you can do in a high-level
  language. Of course _defining_ macros at the preprocessor level in a
  modern language would be unnecessary conservatism, I think that maybe
  seeing syntax like this will be a good thing:

class Foo : GLib.Object
{
        public macro foo(a, b){
                ...
        }
        public static macro bar(....
}

  And have generated vapi files contain public macros so that they can
  be used in a foreign code.

What do you think about these ideas?

best regards,
AW.

Even in C++ you usually avoid the preprocessor for most things, because
preprocessor symbols cannot be scoped. Which is doubly so applicable to vala.

-- 
                                               Jan 'Bulb' Hudec <bulb ucw cz>
_______________________________________________
vala-list mailing list
vala-list gnome org
http://mail.gnome.org/mailman/listinfo/vala-list


-- 
Mój klucz publiczny o identyfikatorze 1024D/E12C5A4C znajduje się na
serwerze hkp://keys.gnupg.net

My public key with signature 1024D/E12C5A4C is on the server
hkp://keys.gnupg.net

Attachment: signature.asc
Description: PGP signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]