Error 089 casting a void function is illegal

A small, statically typed scripting language. Contribute to alliedmodders/sourcepawn development by creating an account on GitHub.
/* Pawn compiler — Error message strings (plain and compressed formats) * * Copyright (c) ITB CompuPhase, 2000-2006 * * This software is provided «as-is», without any express or implied warranty. * In no event will the authors be held liable for any damages arising from * the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software in * a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * Version: $Id$ */ // To find unused errors, try this: // for i in {1..182}; do echo -n «Error $i:» ; grep error compiler/*.cpp | grep -E «b$ib» | wc -l; done static const char* errmsg[] = { /*001*/ «expected token: «%s«, but found «%s«n«, /*002*/ «only a single statement (or expression) can follow each «case«n«, /*003*/ «declaration of a local variable must appear in a compound blockn«, /*004*/ «function «%s« is not implementedn«, /*005*/ «function may not have argumentsn«, /*006*/ «must be assigned to an arrayn«, /*007*/ «operator cannot be redefinedn«, /*008*/ «must be a constant expression; assumed zeron«, /*009*/ «invalid array size (negative, zero or out of bounds)n«, /*010*/ «invalid function or declarationn«, /*011*/ «symbol ‘%s‘ already defined — did you use a methodmap before its declaration?n«, /*012*/ «invalid function call, not a valid addressn«, /*013*/ «no entry point (no public functions)n«, /*014*/ «invalid statement; not in switchn«, /*015*/ ««default« case must be the last case in switch statementn«, /*016*/ «multiple defaults in «switch«n«, /*017*/ «undefined symbol «%s«n«, /*018*/ «initialization data exceeds declared sizen«, /*019*/ «cannot use symbol «%s« before it is fully parsedn«, /*020*/ «invalid symbol name «%s«n«, /*021*/ «symbol already defined: «%s«n«, /*022*/ «must be lvalue (non-constant)n«, /*023*/ «array assignment must be simple assignmentn«, /*024*/ ««break« or «continue« is out of contextn«, /*025*/ «function heading differs from prototypen«, /*026*/ «no matching «#if…«n«, /*027*/ «invalid character constantn«, /*028*/ «invalid subscript (not an array or too many subscripts): «%s«n«, /*029*/ «invalid expression, assumed zeron«, /*030*/ «compound statement not closed at the end of file (started at line %d)n«, /*031*/ «unknown directiven«, /*032*/ «array index out of bounds (variable «%s«)n«, /*033*/ «array must be indexed (variable «%s«)n«, /*034*/ «argument does not have a default value (argument %d)n«, /*035*/ «argument type mismatch (argument %d)n«, /*036*/ «empty statementn«, /*037*/ «invalid string (possibly non-terminated string)n«, /*038*/ «extra characters on linen«, /*039*/ «constant symbol has no sizen«, /*040*/ «duplicate «case« label (value %d)n«, /*041*/ «invalid ellipsis, array size is not knownn«, /*042*/ «invalid combination of class specifiersn«, /*043*/ «character constant exceeds range for packed stringn«, /*044*/ «positional parameters must precede all named parametersn«, /*045*/ «too many function argumentsn«, /*046*/ «unknown array size (variable «%s«)n«, /*047*/ «array sizes do not match, or destination array is too smalln«, /*048*/ «arrays do not matchn«, /*049*/ «invalid line continuationn«, /*050*/ «missing function call, cannot use non-static member function as a valuen«, /*051*/ «overloaded operator ‘%s‘ does not return booln«, /*052*/ «array size exceeds memory capacityn«, /*053*/ «number literal contains alphanumeric charactern«, /*054*/ «unmatched closing brace («}«)n«, /*055*/ «start of function body without function headern«, /*056*/ «arrays, local variables and function arguments cannot be public (variable «%s«)n«, /*057*/ «property «%s« has no getter or settern«, /*058*/ «duplicate argument; same argument is passed twicen«, /*059*/ «function argument may not have a default value (variable «%s«)n«, /*060*/ «multiple «#else« directives between «#if … #endif«n«, /*061*/ ««#elseif« directive follows an «#else« directiven«, /*062*/ «number of operands does not fit the operatorn«, /*063*/ «function result tag of operator «%s« must be «%s«n«, /*064*/ «cannot change predefined operatorsn«, /*065*/ «enum struct fields cannot have more than one dimensionn«, /*066*/ «function argument may not be a reference argument or an array (argument «%s«)n«, /*067*/ «variable cannot be both a reference and an array (variable «%s«)n«, /*068*/ «cannot automatically increment values of type ‘%sn«, /*069*/ «arrays in info structs must be unsized and single dimensionn«, /*070*/ «assertion failed%sn«, /*071*/ «user-defined operator must be declared before use (function «%s«)n«, /*072*/ ««sizeof« operator is only valid on variablesn«, /*073*/ «function argument must be an array (argument «%s«)n«, /*074*/ «#define pattern must start with an alphabetic charactern«, /*075*/ «input line too long (after substitutions)n«, /*076*/ «syntax error in the expression, or invalid function calln«, /*077*/ «arrays cannot be indexed by non-integral type ‘%sn«, /*078*/ «function uses both «return« and «return <value>«n«, /*079*/ «inconsistent return types (array & non-array)n«, /*080*/ «‘…’ not allowed in enum struct initializersn«, /*081*/ «enum struct field arrays must have fixed sizesn«, /*082*/ «properties cannot be arraysn«, /*083*/ «methodmap methods cannot return arraysn«, /*084*/ «cannot call constructor for ‘%s‘ as static methodn«, /*085*/ «type «%s« can only be used in new-style declarationsn«, /*086*/ «number literal has invalid digitsn«, /*087*/ «enum struct «%s« cannot refer to itselfn«, /*088*/ «cannot return a value from a void functionn«, /*089*/ «casting a void function is illegaln«, /*090*/ «public functions may not return arrays (symbol «%s«)n«, /*091*/ «more initializers than enum fieldsn«, /*092*/ «number of arguments does not match definitionn«, /*093*/ «cannot divide by zeron«, /*094*/ «cannot apply const qualifier to enum struct field «%s«n«, /*095*/ «type «%s« cannot be applied as a tagn«, /*096*/ «could not find member «%s« in %s «%s«n«, /*097*/ «overflow in integer divisionn«, /*098*/ «type «%s« should be «%s« in new-style declarationsn«, /*099*/ «%s should not have an explicit return typen«, /*100*/ «function prototypes do not matchn«, /*101*/ «fixed dimensions must be after the array name, not on the typen«, /*102*/ «cannot find %s %sn«, /*103*/ «%s was already defined on this %sn«, /*104*/ «cannot find any methods for %sn«, /*105*/ «cannot find method or property «%s.%s«n«, /*106*/ «invalid expression, must be integraln«, /*107*/ «cannot call methods on a functionn«, /*108*/ «resolution operator (::) can only resolve field offsets of enum structsn«, /*109*/ «%s name must start with an uppercase lettern«, /*110*/ «%s has already been defined (previously seen as %s)n«, /*111*/ «cannot index into enum struct «%s«n«, /*112*/ «resolution operator (::) cannot be used on «%s«n«, /*113*/ «constructor for «%s« already existsn«, /*114*/ «missing type, or %s must have the same name as %s «%s«n«, /*115*/ «cannot use delete, %s %s has no destructorn«, /*116*/ «no methodmap or class was found for %sn«, /*117*/ «enum structs cannot be indexed as arraysn«, /*118*/ «custom destructors are no longer supportedn«, /*119*/ «enum struct «%s« must have at least one fieldn«, /*120*/ «methodmap and class signatures must use new-style type declarationsn«, /*121*/ «cannot specify array dimensions on both type and namen«, /*122*/ «expected type expressionn«, /*123*/ «fully-qualified name «%s« is too long, would be truncated to «%s«n«, /*124*/ «unexpected token, expected method or propertyn«, /*125*/ «expected «native«, «get«, or «set«n«, /*126*/ «%s for %s already existsn«, /*127*/ «property getters cannot accept extra argumentsn«, /*128*/ «cannot return an array of indeterminate lengthn«, /*129*/ «cannot mix methodmaps and classes with inheritancen«, /*130*/ «cannot coerce functions to valuesn«, /*131*/ «cannot coerce object type %s to non-object type %sn«, /*132*/ «cannot coerce non-object type %s to object type %sn«, /*133*/ «cannot coerce unrelated object types %s and %sn«, /*134*/ «type mismatch (expected «%s«, got «%s«)n«, /*135*/ «cannot use enum struct type «%s« in nativesn«, /*136*/ «reference is redundant, enum struct types are array-liken«, /*137*/ «cannot mix reference and array typesn«, /*138*/ «const was specified twicen«, /*139*/ «could not find type «%s«n«, /*140*/ «function ‘%s‘ does not return a valuen«, /*141*/ «natives, forwards, and public functions cannot return arraysn«, /*142*/ «unexpected array expressionn«, /*143*/ «new-style declarations should not have «new«n«, /*144*/ «void cannot be used as a variable typen«, /*145*/ «invalid type expressionn«, /*146*/ «#pragma newdecls must be required or optionaln«, /*147*/ «new-style declarations are requiredn«, /*148*/ «cannot assign null to a non-nullable typen«, /*149*/ «no getter found for property %sn«, /*150*/ «setter must take exactly one extra argument with type %sn«, /*151*/ «unmatched opening brace (‘{‘) (line %d)n«, /*152*/ «no setter found for property %sn«, /*153*/ «Array-based enum structs have been removed. See https://wiki.alliedmods.net/SourcePawn_Transitional_Syntax#Enum_Structsn«, /*154*/ «cannot assign INVALID_FUNCTION to a non-function typen«, /*155*/ «expected newline, but found ‘%sn«, /*156*/ «invalid ‘using’ declarationn«, /*157*/ «%s‘ is a reserved keywordn«, /*158*/ «multi-tags are no longer supportedn«, /*159*/ «brackets after variable name indicate a fixed-size array, but size could not be determined — « «either specify sizes, an array initializer, or use dynamic syntax (such as ‘char[] x’)n«, /*160*/ «brackets in between type and variable name indicate a dynamic-size array, but a fixed-size « «initializer was givenn«, /*161*/ «brackets after variable name indicate a fixed-size array, but a dynamic size was given — did « «you mean to use ‘new %s[size]’ syntax?n«, /*162*/ «cannot create dynamic arrays in global scope — did you mean to « «create a fixed-length array?n«, /*163*/ «indeterminate array size in «sizeof« expression (symbol «%s«)n«, /*164*/ «allocated array type ‘%s‘ doesn’t match original type ‘%sn«, /*165*/ «cannot create dynamic arrays in static scope — did you mean to create a fixed-length array « «with brackets after the variable name?n«, /*166*/ «cannot use ‘this’ outside of a methodmap method or propertyn«, /*167*/ «cannot use delete, %s do not have destructorsn«, /*168*/ «re-tagging enums is no longer supportedn«, /*169*/ «cannot tag an enum as implicit-intn«, /*170*/ «creating new object ‘%s‘ requires using ‘new’ before its constructorn«, /*171*/ «cannot use ‘new’ with non-object-like methodmap ‘%sn«, /*172*/ «methodmap ‘%s‘ does not have a constructorn«, /*173*/ «%s‘ is a newly reserved keyword that may be used in the future; use a different name as an « «identifiern«, /*174*/ «symbol ‘%s‘ is a type and cannot be used as a valuen«, /*175*/ «constructors cannot be staticn«, /*176*/ «non-static method or property ‘%s‘ must be called with a value of type ‘%sn«, /*177*/ «static method ‘%s‘ must be invoked via its type (try ‘%s.%s‘)n«, /*178*/ «cannot coerce %s[] to %s[]; storage classes differn«, /*179*/ «cannot assign %s[] to %s[], storage classes differn«, /*180*/ «function return type differs from prototype. expected ‘%s‘, but got ‘%sn«, /*181*/ «function argument named ‘%s‘ differs from prototypen«, /*182*/ «functions that return arrays cannot be used as callbacksn«, /*183*/ «brackets after variable name indicates a fixed-size array, but « «size is missing or not constantn«, /*184*/ «implicit dynamic array has a dimension of unspecified sizen«, /*185*/ «invalid default array initializern«, }; static const char* warnmsg[] = { /*200*/ «symbol «%s« is truncated to %d charactersn«, /*201*/ «redefinition of constant/macro (symbol «%s«)n«, /*202*/ «number of arguments does not match definitionn«, /*203*/ «symbol is never used: «%s«n«, /*204*/ «symbol is assigned a value that is never used: «%s«n«, /*205*/ «redundant code: constant expression is zeron«, /*206*/ «redundant test: constant expression is non-zeron«, /*207*/ «unknown #pragman«, /*208*/ «function with tag result used before definition, forcing reparsen«, /*209*/ «function has explicit ‘int’ tag but does not return a valuen«, /*210*/ «possible use of symbol before initialization: «%s«n«, /*211*/ «possibly unintended assignmentn«, /*212*/ «possibly unintended bitwise operationn«, /*213*/ «tag mismatch (expected «%s«, got «%s«)n«, /*214*/ «possibly a «const« array argument was intended: «%s«n«, /*215*/ «expression has no effectn«, /*216*/ «nested commentn«, /*217*/ «inconsistent indentation (did you mix tabs and spaces?)n«, /*218*/ «old style prototypes used with optional semicolumnsn«, /*219*/ «local variable «%s« shadows a variable at a preceding leveln«, /*220*/ «expression with tag override must appear between parenthesesn«, /*221*/ «label name «%s« shadows tag namen«, /*222*/ «number of digits exceeds rational number precisionn«, /*223*/ «redundant «sizeof«: argument size is always 1 (symbol «%s«)n«, /*224*/ «user warning: %sn«, /*225*/ «unreachable coden«, /*226*/ «a variable is assigned to itself (symbol «%s«)n«, /*227*/ «illegal charactern«, /*228*/ «enum multiplers are deprecated and will be removed in the next releasen«, /*229*/ «index tag mismatch (symbol «%s«)n«, /*230*/ «symbol «%s« is not a preprocessor symbol; this behavior is undefined and will be removed in the futuren«, /*231*/ «unused231n«, /*232*/ «output file is written, but with compact encoding disabledn«, /*233*/ «unused233n«, /*234*/ «symbol «%s« is marked as deprecated: %sn«, /*235*/ «unused235n«, /*236*/ «unused236n«, /*237*/ «coercing functions to and from primitives is unsupported and will be removed in the futuren«, /*238*/ «%s:’ is an illegal cast; use view_as<%s>(expression)n«, /*239*/ «%s‘ is an illegal tag; use %s as a typen«, /*240*/ «%s:’ is an old-style tag operation; use view_as<type>(expression) insteadn«, /*241*/ «scalar assignment to array is deprecated; use «{ <val>, … }« insteadn«, /*242*/ «function «%s« should return an explicit valuen«, /*243*/ «syntax is deprecated; use parenthesis insteadn«, /*244*/ «field ‘%s‘ was specified twicen«, /*245*/ «function %s implements a forward but is not marked as publicn«, /*246*/ «function %s returns an array but return type is not marked as an arrayn«, /*247*/ «include paths should be enclosed in «quotes« or <angle brackets>n«, /*248*/ «character is not utf-8 encodedn«, /*249*/ «function name is always true — possible missing parenthesis?n«, /*250*/ «pragma has no effectn«, /*251*/ «const variable was not initializedn«, }; static const char* errmsg_ex[] = { /*400*/ «function «%s« must return a valuen«, /*401*/ «cannot specify ‘…’ arguments more than oncen«, /*402*/ «cannot specify additional arguments after ‘…’n«, /*403*/ «not yet implementedn«, /*404*/ «enum multiplers are no longer supportedn«, /*405*/ «invalid assignmentn«, /*406*/ «operator %s(%s) was used before declarationn«, /*407*/ «operator %s(%s, %s) was used before declarationn«, /*408*/ «recursion detected in user operatorn«, /*409*/ «methodmap %s referenced before definitionn«, /*410*/ «methodmap inheritance forms a cyclen«, /*411*/ «cannot determine fixed array size of return valuen«, /*412*/ «function %s implements a forward but is not marked as publicn«, /*413*/ «returned array does not have the same dimension count as return typen«, /*414*/ «include statements are only allowed at the top-level scopen«, /*415*/ «assertion failedn«, /*416*/ «user error: %sn«, /*417*/ «cannot read from file: «%s«n«, /*418*/ «deprecated syntax; see https://wiki.alliedmods.net/SourcePawn_Transitional_Syntax#Typedefsn«, /*419*/ «cannot write to file: «%s«n«, /*420*/ «unhandled AST type: %dn«, /*421*/ «too many functionsn«, /*422*/ «no more source locations, too much source textn«, /*423*/ «internal compiler error: error propagated with no messagen«, /*424*/ «integer literal contains no digitsn«, /*425*/ «exponential must be followed by integern«, /*426*/ «macro arguments must be %% followed by a single digitn«, /*427*/ «macro argument %%%d already usedn«, /*428*/ «invalid macro argument, mismatched parenthesisn«, /*429*/ «wrong number of macro arguments (expected %s, got %s)n«, /*430*/ «invalid macro definitionn«, /*431*/ «script uses too much memory, cannot compilen«, /*432*/ «type %s was already declared as %sn«, };

I’m getting an «invalid use of void expression» error regarding the following function:

void remove_data(char* memory, char* bitmap, int pos)
{
    int i;

    i = (int)test_bit(bitmap, pos-1);

    if(i != 0)
    {
        memory[pos-1] = NULL;
        toggle_bit(bitmap, pos-1);
    }
}

Now from what I’ve read on other threads regarding this similar issue this error pops up when the programmer uses something within the function that will generate an output. However, I’m failing to see what would cause that in the code I’ve written.

Edit to add:

The toggle bit function used in it is also type void and doesn’t return a value.

void test_bit(char * bitmap, int pos)
{
    int bit;

    bit = bitmap[pos/8] & (1<<(pos%8));
    printf("%dn", &bit);
}

I commented the printf line in test_bit but the error is still there.

asked Oct 8, 2012 at 16:55

Kali's user avatar

KaliKali

291 gold badge1 silver badge3 bronze badges

6

However, I’m failing to see what would cause that in the code I’ve written.

Me too, because I don’t think you have posted the relevant code. Regardless, I think this is probably your problem:

i = (int)test_bit(bitmap, pos-1);

Please show us the signature for test_bit. I’m guessing it returns void or you have forward declared it somewhere and accidentally wrote:

void test_bit(char*, int);

Since the function returns void (i.e., nothing) you cannot then proceed to cast the return value (which is nothing) to an int as you are doing, it makes no sense and is illegal.

EDIT: You have verified in the comments that test_bit is in fact declared to return void, so that’s your problem.

answered Oct 8, 2012 at 16:58

Ed S.'s user avatar

Ed S.Ed S.

122k21 gold badges181 silver badges262 bronze badges

Since test_bit is void, you may not use its return (as in i = (int)test_bit(bitmap, pos-1);) — there is no return value.

answered Oct 8, 2012 at 16:59

mah's user avatar

mahmah

38.8k9 gold badges75 silver badges93 bronze badges

Obvious Solution: Don’t assign results of function returning void.

Non-Obvious Solution: Don’t nest function calls, and you are less likely
to be looking in all of the wrong spots, thinking the compiler is broken.

#include <stdio.h> //:for: printf(...)

void YOUR_MISTAKE_ACTUALLY_HERE();
void  MyFunc( void );
void* WRAPPED_MyFunc( int, int, int );


int main( void ){
    printf("[BEG:main]n");


    void* HW = NULL;
    HW = WRAPPED_MyFunc(  //:<---So you check this, but it looks fine.
        1
    ,   YOUR_MISTAKE_ACTUALLY_HERE()
    ,   3
    );; //:<--- compiler says "Invalid Use Of Void Expression" Here.

    if( HW ){ /** NOOP **/ };


    printf("[END:main]n");
} 

    void YOUR_MISTAKE_ACTUALLY_HERE(){ }

    //:Pretend this function is fetched from DLL.
    //:Casting all DLL functions initially to void(*pfn)void
    //:in a lookup table, then re-casting later.
    void MyFunc( void ){

        return;

    }//[;]//

    typedef  
        void* 
        (* MyFunc_TYPEDEF)(            

            int a
        ,   int b
        ,   int c

        );

    void*
    WRAPPED_MyFunc(

        int a
    ,   int b
    ,   int c

    ){


               MyFunc_TYPEDEF
        fun =( MyFunc_TYPEDEF)
               MyFunc;

        void* ret=( fun(

            a
        ,   b
        ,   c

        ));

        return( 
            (void*)
            ret 
        );;

    }//:Func

answered Dec 9, 2019 at 3:39

KANJICODER's user avatar

KANJICODERKANJICODER

3,47729 silver badges16 bronze badges

You wrote

 i = (int)test_bit(bitmap, pos-1);

Why have a cast?

Seems a bit wrong when the function is

void test_bit(char * bitmap, int pos)
{
    int bit;

    bit = bitmap[pos/8] & (1<<(pos%8));
    printf("%dn", &bit);
}

You can’t convert a void into an integer.

Dharman's user avatar

Dharman

29.3k21 gold badges80 silver badges131 bronze badges

answered Oct 8, 2012 at 17:05

Ed Heal's user avatar

Ed HealEd Heal

58.6k17 gold badges87 silver badges125 bronze badges

0

Good question!

There is nothing special about void **. It’s just a pointer which yields an lvalue of type void * when it is dereferenced. It is not compatible with int **.

The standard says you can convert any pointer into a void pointer and then back to a compatible one, e.g.

int x, *p = &x;
void *q = p;
const char *c = q;
int *d = q;

is allowed, because we convert q back to compatible pointer, and something similar happens e.g. in a naive implementation of memcpy(3).

However, the standard doesn’t promise that pointers of different type have comparable representations, so it’s technically possible that the bit pattern of p and q are different, and when converting to and from a void pointer more than copying happens. For this reason when you do

*(void **)p = malloc(...);

it’s not certain that x contains a valid address to an int. Do you see how this is different from the suggestion from the F.A.Q.? On any platform I can think of this will probably work, but you never know how future compiler versions might optimize code like that. Beside all that, I fear that an API like that is error prone, because it will literally accept any pointer, not just pointers to pointers.

I’m defining an attachinterrupt and I’m running into an error. The line in question is:

void setup() {
   attachInterrupt(digitalPinToInterrupt(stallsense1), changedirection(1), RISING);
   attachInterrupt(digitalPinToInterrupt(stallsense2), changedirection(2), RISING);
}

and the error I’m getting is:

error: invalid use of void expression
attachInterrupt(digitalPinToInterrupt(stallsense2), changedirection(2), RISING);
                                                                                ^
exit status 1
invalid use of void expression

The idea is I have one function changedirection and two possible inputs, either 1 or 2.
I believe the issue is where I’ve called the function changedirection(1). I want to simply tell attachinterrupt to call the function changedirection with an input of either 1 or 2. How would I do this?

jsotola's user avatar

jsotola

1,2142 gold badges10 silver badges18 bronze badges

asked Jun 17, 2021 at 22:58

Jules's user avatar

attachInterrupt expects a simple pointer to function taking no arguments and returning nothing (void).

So, really there’s no way to directly do what you’re talking about. There’s no currying ability builtin. You can define your own functions like

void proxy_changedirection_1() {
    changedirection(1);
}

And then attachInterrupt specifying proxy_changedirection_1, or you can use a lambda with no captures for the same purpose:

attachInterrupt(
    digitalPinToInterrupt(stallsense1),
    [] () {
        changedirection(1);
    },
    RISING
);

answered Jun 17, 2021 at 23:17

timemage's user avatar

timemagetimemage

4,6211 gold badge10 silver badges24 bronze badges

1

What happened is you wrote a void expression where an expression of type ‘pointer to function of void returning void’ (i.e., no arguments and no return value), was expected. The name of a function with no parentheses for an argument list is an expression of type ‘pointer to function’ taking whatever arguments & types that named function was declared to expect, and returning whatever type that named function was declared to return.

But if you write the parentheses with it, now you’ve written an expression that 1) would (if it were valid) get evaluated during the call to attachInterrupt() — much earlier that you want it to be! — and return a value of that return type rather than the type you expected.

@timemage has offered two ways to solve this.

answered Jun 17, 2021 at 23:34

JRobert's user avatar

JRobertJRobert

14.7k3 gold badges19 silver badges49 bronze badges

  • Remove From My Forums
  • Question

  • Hello all:

    I have the following function and when I compile it under VS.NET 2005, the following compile warnings show up:

    Warning 1 warning C4311: ‘type cast’ : pointer truncation from ‘void *’ to ‘long’ c:temptestonelibutils.c 56 
    Warning 2 warning C4312: ‘type cast’ : conversion from ‘unsigned long’ to ‘void *’ of greater size c:temptestonelibutils.c 56 

    Code Snippet

    /*
    *  Dynamically allocate a 2d (x*y) array of elements of size _size_ bytes.
    */
    void **MatrixIB (unsigned long x, unsigned long y, int size)
    {
        void    *ptr;
        void    **returnPtr;
        register unsigned long    i, j;

        returnPtr = (void **) malloc (x * sizeof(void *));
        ptr = (void *) malloc (x * y * size);

        for (i=0, j=0; j<x; i+=(y*size), j++)
        {
            returnPtr[j] = (void *) ((long)ptr + i);  // <<< Compile Warnings
        }

        return ((void **) returnPtr);
    } /* Matrix() */

    I made the following modification

    I> returnPtr[j] = (void *) (ptr + i);  // <<< Compile Errors

    Error 1 error C2036: ‘void *’ : unknown size c:temptestonelibutils.c 57 

    2> returnPtr[j] = (void *) ((long*)ptr + i);  // <<< No compile errors

    3> returnPtr[j] = (void *) ((char*)ptr + i);  // <<< No compile errors

    I think the solution 3> should be the correct one.

    If any, how can the original function works without errors if we just ignore the warning.

    (i.e. Use returnPtr[j] = (void *) ((long)ptr + i);  )

    Based on the design of this function, which modification is right. Or, they are all wrong.

    Thank you very much

    -Daniel

Answers

  • Hello Daniel,

      You are getting warnings due to casting a void* to a type of a different size.  On a 64-bit Windows computer, ‘long’ is a 32-bit type, and all pointers are 64-bit types.  So, when you cast a (void*) to (long), you are losing 32 bits of data in the conversion.  Losing bytes like this is called ‘truncation’, and that’s what the first warning is telling you.  From that point on, you are dealing with 32 bits.  However, you are also casting the result of this operation to (void*).  Since all pointers on 64-bit Windows are 64 bits, you are growing the data size from 32 bits back to 64 bits.  This is what the second warning is telling you.  To avoid truncating your pointer, cast it to a type of identical size.  You can use any other pointer, or you can use (size_t), which is 64 bits.

      Even if you are compiling your program for a 32-bit computer, you should fix your code to remove these warnings, to ensure your code is easily portable to 64-bit.

      Next, when doing pointer arithmetic, the addition operation will use the pointer’s type to determine how many bytes to add to it when incrementing it.  For example, if you write ((int*)ptr + 1), it will add 4 bytes to the pointer, because «ints» are 4 bytes each.  If you write ((char*)ptr + 1), it will advance the pointer 1 byte, because a «char» is 1 byte.  The code ((void*)ptr + 1) does not work, because the compiler has no idea what size «void» is, and therefore doesn’t know how many bytes to add.  This is why you got Error 1 C2036, from your post.

      Since the ‘size’ argument for your function is the number of bytes each element in the array needs, I think casting the pointer to (char*) is appropriate.  So, solution #3 works just fine.

      Alternatively, if you choose to cast the ptr variable to (size_t) instead, then you don’t need to worry about the pointer type anymore.  You could use this code, and it would do the same thing as casting ptr to (char*)


    returnPtr[j] = (void*)((size_t)(ptr) + i);

    I hope that helps!

Цитата
Сообщение от doka

а покажи как вызываешь?

Локализуй ошибку:

Сделай Sub CrPMailTest() и вызови её. Если ошибку не выдаст, то добавляй по-одному парамметры (Sub CrPMailTest(txt As String); Sub CrPMailTest(subj As String, txt As String))

вызов делаю так Call CrPMail(doc,who$,whoserver$,subj$,txt$), передаваемые параметры и их значения я попытался описать в первом посте. Сама функция отрабатывает на одном сервере в домене A, но на другом, в другом домене Б, где стоит не связанная реплика (одностороняя репликация из A в Б ) у некоторых пользователей (домена Б) выводит такую ошибку (сказать что у всех не могу), склоняюсь к предположению Morpheus, такое впечатление не хватает доступа у пользователя для вызова. Проверить толком не могу ограничен там в правах, кстати оба модуля подписал своей учеткой, может в этом проблема.
Сервер Win на оси 2003 , но действительно использую в subj$ конструкцию Chr$(10)+Chr$(13).
Пробовал сам в домене Б выполнить эту конструкцию, получаю ошибку, в A делаю все ок.

Для Kee_Keekkenen
ошибок компиляции нету, я же написал что в одном случае все работает на ура, мусора тоже нет, уже шаманил с полным пересозданием модулей, пока результатов нет. Считаю. что права тянут.

Что в плане прав можно проверить у моей учетки в домене B, какой минимум необходим для успешного выполнения ?

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Error 08001 timeout expired
  • Error 08 шерхан mobicar
  • Error 079 inconsistent return types array non array
  • Error 078 function uses both return and return value
  • Error 075 input line too long after substitutions павно

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии