May 13, 2016
On Thursday, 12 May 2016 at 22:51:17 UTC, Andrew Edwards wrote:
> The following preprocessor directives are frequently encountered in C code, providing a default constant value where the user of the code has not specified one:
>
> 	#ifndef MIN
> 	#define MIN     99
> 	#endif
>
> 	#ifndef MAX
> 	#define MAX     999
> 	#endif
>
> I'm at a loss at how to properly convert it to D. I've tried the following:
>
> 	enum MIN = 0;
> 	static if(MIN <= 0)
> 	{
> 		MIN = 99;
> 	}
>
> it works as long as the static if is enclosed in a static this(), otherwise the compiler complains:
>
> 	mo.d(493): Error: no identifier for declarator MIN
> 	mo.d(493): Error: declaration expected, not '='
>
> This however, does not feel like the right way to do thinks but I cannot find any documentation that provides an alternative. Is there a better way to do this?
>
> Thanks,
> Andrew

One thing you could try is compile the C code without the #ifndef's and see if it compiles without issues. If it does, simply use a D enum and don't worry about translating the #ifndef's.

(Alternately check the C code to see if there really are differing definitions of MIN/MAX -- if there are, then the code is already messed up and you need to implement your D code taking into consideration the implications of that -- maybe use different variable names in each section of the code for the MIN/MAX that takes the different MIN/MAX values. I've typically seen this kind of ifdef'ing to quick-fix compile issues in new code without having to rewrite a whole bunch of existing code or code-structure and it is never to have differing values for the defines -- if differing values are used with the same name, then the code is bad and it's best to cleanup as you migrate to D.)
May 14, 2016
On 5/14/16 12:35 AM, Steven Schveighoffer wrote:
> On 5/13/16 12:59 AM, Andrew Edwards wrote:
>> On 5/13/16 8:40 AM, Andrew Edwards wrote:
>>>> That seems wrong. You can't assign to an enum. Besides, doesn't your
>>>> declaration of MIN shadow whatever other definitions may be
>>>> currently in
>>>> effect?
>>>
>>> Okay, got it. It seams I just hadn't hit that bug yet because of other
>>> unresolved issues.
>>>
>>>> Perhaps what you meant is something like this?
>>>>
>>>>     static if (!is(typeof(MIN) : int))
>>>>         enum MIN = 99;
>>>
>>> This seems to do the trick.
>>
>> But not exactly the way it's expected to. In the snippets below, C
>> outputs 10 while D outputs 100;
>>
>> min.c
>> =========================
>>      #define MIN 10 // [1]
>>
>>      #include "mild.h"
>>
>>      int main()
>>      {
>>              print();
>>              return 0;
>>      }
>>
>> min.h
>> =========================
>>      #include <stdio.h>
>>
>>      #ifndef MIN
>>      #define MIN 100
>>      #endif
>>
>>      void print()
>>      {
>>          printf("%d\n", MIN);
>>      }
>>
>> minA.d
>> =========================
>>      enum MIN = 10; // [1]
>>
>>      import minB;
>>
>>      void main()
>>      {
>>          print();
>>      }
>>
>> minB.d
>> =========================
>>      static if (!is(typeof(MIN) : int))
>>          enum MIN = 100;
>>
>>      void print()
>>      {
>>              import std.stdio: writeln;
>>              writeln(MIN);
>>      }
>>
>> Is there a way to reproduce the same behavior? Are there reason's for
>> not allowing this functionality or am I just misunderstanding and going
>> about things the wrong way?
>
> Code like this is FUBAR.
>
> I have seen abuse of pre-processor in many places, and it never
> justifies the cleverness of how it is done.

This may be the case, but since I am not yet at a level of understanding where I can discern what is justifiable or not. At the moment I'm simply trying to port over 15k LOC so that I can play with it in D and improve my understanding of what's going on.

> Note that min.h is providing an inlined function. Essentially, min.h is
> like a template with the definition of the template parameter defined by
> the including file. But you can only ever include min.h ONCE in your
> entire project, or you will get linker errors.

This was an extremely simplified example. There is far more going than than this. Just trying not to lose any of the functionality until I understand what why things are done the way they are and how to better do it in D.

> D will always compile a module without external configuration. That is,
> print is compiled ONCE and only in the context that minA.d defines.
> Inlining can replace the print call with inline functions, but it will
> still be compiled according to the module's definitions, not external.
>
> TL;DR: there isn't a good way to port this code, because it's shit code,
> and D doesn't do that :)
>
> -Steve

May 16, 2016
On Thursday, 12 May 2016 at 22:51:17 UTC, Andrew Edwards wrote:
> The following preprocessor directives are frequently encountered in C code, providing a default constant value where the user of the code has not specified one:
>
> 	#ifndef MIN
> 	#define MIN     99
> 	#endif
>
> 	#ifndef MAX
> 	#define MAX     999
> 	#endif

One option here is that the programmer is trying to avoid multiple definitions of MIN and MAX if for some reason this header is included together with another header that also defines a MIN and MAX.

So, you might start by checking if any other header/source file does so.  It's entirely possible the programmer is just going overkill with the kind of stuff one does to guard against multiple #include's of the same header, and that this header is the _only_ place where MIN and MAX are defined, and that it's ALWAYS valid for them to be 99 and 999 respectively.

The other thought is that the programmer might have in mind to be able to choose alternative MIN and MAX at compile time via environment variables (perhaps the project's build scripts make use of this?).  If you think so, is that something you want to support?  There are probably better ways of achieving the same result.

I suspect it'll probably turn out to be fine to just use

    enum MIN = 99;
    enum MAX = 999;

... but H. S. Teoh's suggestion looks sane as a more cautious alternative.
1 2
Next ›   Last »