Page 1 of 1

Qué es lo erróneo?

Posted: Tue Jan 15, 2019 5:18 pm
by FranciscoA
Amigos:
Alguno de ustedes puede decirme, ¿que es lo malo en el siguiente codigo?

Code: Select all

#DEFINE USAR_PRINTLIB  IF( Type("VerImpMetaF()") == "U", 0, 1 )

Function Main()

MSGINFO( USAR_PRINTLIB )

#if USAR_PRINTLIB == 0        //Aqui salta el error en tiempo de compilacion Error E0025  Error in #if expression
   #undef USAR_PRINTLIB
   MsgInfo("NO ESTA LINKEADA")
#endif

Return nil

 

Re: Qué es lo erróneo?

Posted: Tue Jan 15, 2019 5:23 pm
by FranciscoA
Tambien lo hice asi, y el mismo resultado.
Syntax
#if <condition1>
<statements1>
[ #elif <conditionN>
<statmentsN> ]
[ #else
<statments> ]
#endif

Arguments
<condition1> .. <conditionN>
<condition> is one or more logical conditions that are resolved by the preprocessor. Conditions are formulated using #define constants, numeric or logical literal values. A condition expression may include comparison operators.
<statements1> .. <statementsN>
<statements> is the program code to include in the preprocessor output when a condition is true. Description

Code: Select all

#DEFINE USAR_PRINTLIB  IF( Type("VerImpMetaF()") == "U", 0, 1 )
#DEFINE NO_USARLA      0

Function Main()

#if USAR_PRINTLIB == NO_USARLA        //Aqui salta el error en tiempo de compilacion Error E0025  Error in #if expression
   #undef USAR_PRINTLIB
   MsgInfo("NO ESTA LINKEADA")
#endif

Return nil

Re: Qué es lo erróneo?

Posted: Tue Jan 15, 2019 5:34 pm
by hmpaquito
1. Tal como le indicó aquí (http://forums.fivetechsupport.com/viewt ... 00#p218321) el master Antonio, hay que preguntar por UI y no simplemente por U.

2. Como directiva de compilacion el #if A == B es erróneo.

Re: Qué es lo erróneo?

Posted: Tue Jan 15, 2019 5:59 pm
by FranciscoA
hmpaquito wrote:1. Tal como le indicó aquí (http://forums.fivetechsupport.com/viewt ... 00#p218321) el master Antonio, hay que preguntar por UI y no simplemente por U.

2. Como directiva de compilacion el #if A == B es erróneo.

1 - Cuando uso Type("VerImpMetaF()"), el resultado es "U".
"U" NIL, local or static variable, or not linked-in function
"UE" syntax error in the expression or invalid arguments
"UI" function with non-reserved name was requested

2 - tomado del manuel de xHarbour
The #if..#elif..#else..#endif directives are used for conditional compilation. They work analogous to the IF..ELSEIF..ELSE..ENDIF statements, but are resolved by the preprocessor, rather than the compiler. In contrast to the #ifdef and #ifndef directives, which test only the presence or absence of #define constants, #if allows for testing the values of such constants and comparing them with other values. In addition, multiple conditions can be formulated using #if..#elif. When the #else directive is used, it must be the last one, followed by #endif.
The statements following the first condition that resolves to True is included in the preprocessor output. All other statements are discarded. That means, even if multiple conditions are True, only one of the code statements appears in the preprocessor output. When all conditions are False, the statements following the #else directive, if present, are used.
The following rules are applied by the preprocessor to evaluate a condition:

1. A numeric literal <> 0 yields True, while exact zero yields False.
2. The logical literal .T. is True, .F. is False.
3. #define constants with no associated value yield False.
4. The literal value NIL yields False.
5. Other literal values cannot be used and result in a compile error.
6. Numeric values can be compared using the comparison operators !=, #, >, >=, =, ==, =< and <. The True/False result of the comparison is evaluated by the preprocessor.

// The example demonstrates how the same source code file can be
// compiled for different program versions. Depending on the #define
// constant MAKE_VERSION, differen initilization routines are called.

#define FULL_VERSION 3
#define RESTRICTED_VERSION 2
#define DEMO_VERSION 1

#define MAKE_VERSION RESTRICTED_VERSION

PROCEDURE Main
#if MAKE_VERSION > RESTRICTED_VERSION
InitFullPackage()
#elif MAKE_VERSION > DEMO_VERSION
InitRestrictedPackage()
#else
InitDemoPackage()
#endif

Code: Select all

#DEFINE USAR_PRINTLIB  IF( Type("VerImpMetaF()") == "U", 0, 1 )
#DEFINE NO_USARLA      0

Function Main()

#if USAR_PRINTLIB > NO_USARLA        //Aqui salta el error en tiempo de compilacion Error E0025  Error in #if expression
   MsgInfo("ESTA LINKEADA")
#elif USAR_PRINTLIB == NO_USARLA        //Aqui salta el error en tiempo de compilacion Error E0025  Error in #if expression
   #undef USAR_PRINTLIB
   MsgInfo("NO ESTA LINKEADA")
#endif

Return nil

Re: Qué es lo erróneo?

Posted: Tue Jan 15, 2019 6:04 pm
by hmpaquito
1. ok entendido, mi error.

2. Lo que no se pueden usar son expresiones que deben ser procesadas en tiempo de ejecucion.
No es lo mismo #if 1 > 0 que #if Len("paco") > len("Francisco"). La primera se puede resolver en tiempo de compilacion, que es el "tiempo" de las directivas del compilador. La segunda no.

Re: Qué es lo erróneo?

Posted: Tue Jan 15, 2019 6:14 pm
by FranciscoA
Gracias hmpaquito, por tu interés.
Aún continúa el error.

Re: Qué es lo erróneo?

Posted: Tue Jan 15, 2019 6:38 pm
by EBM
Hola

Creo que el problema puede venir en que los DEFINES se resuelven en tiempo de compilación y el llamado a la función Type se resuelve en ejecución, a los defines debes ponerles valores constantes, tu ejemplo compila correctamente de la siguiente manera:

// #DEFINE USAR_PRINTLIB IF( Type("VerImpMetaF()") == "U", 0, 1 )

Function Main()
LOCAL USAR_PRINTLIB := IF( Type("VerImpMetaF()") == "U", 0, 1 )

MSGINFO( USAR_PRINTLIB )

if USAR_PRINTLIB == 0 //Aqui salta el error en tiempo de compilacion Error E0025 Error in #if expression
// #undef USAR_PRINTLIB
MsgInfo("NO ESTA LINKEADA")
endif

Return nil

Saludos

Eduardo Borondon Muñiz

Re: Qué es lo erróneo?

Posted: Tue Jan 15, 2019 8:13 pm
by FranciscoA
Eduardo.
Gracias por contestar.
Estoy de acuerdo que asi compila sin problemas, pero no es lo que busco.

Lo que quiero hacer es, en base al valor asignado a DEFINE USAR_PRINTLIB mediante la funcion Type(NombreFunctEnLib), (que lo toma correctamente),
es usar ese valor (cuando es 0) para #UNDEF USAR_PRINTLIB.

Posteriormente usariamos en el menu:
MENUITEM "Opciones"
MENU
MENUITEM "UNO" ACTION XXX
#IFDEF USAR_PRINTLIB
MENUITEM "Hola" ACTION NombreFunctEnLib()
#ENDIF
...

Es decir, condicionar el MENUITEM conforme a si fué, o no, linkeada la libreria que contiene la function NombreFunctEnLib) descrita.

Saludos.

Re: Qué es lo erróneo?

Posted: Wed Jan 16, 2019 8:28 am
by hmpaquito
FranciscoA wrote:Lo que quiero hacer es, en base al valor asignado a DEFINE USAR_PRINTLIB mediante la funcion Type(NombreFunctEnLib), (que lo toma correctamente),
es usar ese valor (cuando es 0) para #UNDEF USAR_PRINTLIB.
No lo veo posible por dos motivos:

Primero, como comenté la evaluacion de Type() se realiza en tiempo de ejecución y
Segundo, Harbour compila módulo (.prg) a módulo, y sólo al final, en el linkado, conoce si una función fue enlazada o no.

Hay que montar el sistema de otra forma. Por ejemplo, al compilar detectar si existe un determinado archivo y si existe se pasa una define (-D)

Re: Qué es lo erróneo?

Posted: Wed Jan 16, 2019 7:32 pm
by xmanuel

Code: Select all

Function Main()
    LOCAL USAR_PRINTLIB := IF( Type(VerImpMetaF()) == "U", 0, 1 )

    if USAR_PRINTLIB == 0 
        MsgInfo("NO ESTA LINKEADA")
    endif

Return nil