pgcc compilation error

Dear Mat and others,

There is a problem that occurs with pgcc when compiling what seems to be a simple C code. It does not happen when I try using gcc:

$ /usr/pgi/linux86/6.0/bin/pgcc -c -O2 -DLINUX -Df2cFortran -DPGS_DAAC -DLINUX -DSUNCC -DPROTO -I/HDF4.2r1/include -I/tk/include -I/tk/include/FF  findvar.c -o /tk/obj/linux/AA/findvar.o
PGC-S-0059-Struct or union required on left of . or -> (findvar.c: 39)
PGC-W-0095-Type cast required for this conversion (findvar.c: 39)
PGC/x86 Linux/x86 6.0-5: compilation completed with severe errors

Since the code is fairly small, I’m including all of it bellow:

/*
 * NAME:	ff_find_variable
 *		
 * PURPOSE:	This function does a case sensitive search of a format for a
 *						variable with a given name.
 *  		
 * AUTHOR:	T. Habermann, NGDC, (303) 497 - 6472, haber@ngdc.noaa.gov
 * 		
 * USAGE:	ff_find_variable(char *name, FORMAT_PTR format)
 *			
 * ERRORS:	
 *		Pointer not defined,"Variable Name"
 *		Pointer not defined,"format"
 *		Possible memory corruption, format->name
 * 	
 * COMMENTS:
 * 	
 * RETURNS:	A pointer to the variable if it exists, NULL if it doesn't
 *
 * SYSTEM DEPENDENT FUNCTIONS:
 *  	   
 */ 

#include <freeform.h>

#undef ROUTINE_NAME

#define ROUTINE_NAME "ff_find_variable"

VARIABLE_PTR ff_find_variable(char *name, FORMAT_PTR format)
{
	VARIABLE_LIST_PTR v_list = NULL;

	/* Error checking on Pointers */
	assert(name && format && (format == format->check_address) );

	v_list = FFV_FIRST_VARIABLE(format);

	while(dll_data(v_list)){
		if(memStrcmp(name, FFV_VARIABLE(v_list)->name,NO_TAG) == 0)
			return(FFV_VARIABLE(v_list));	/* name in list */
		v_list = dll_next(v_list);
	}
	return(NULL);		/* Not in list */
}

Line 39 where the error occurs is this one:

if(memStrcmp(name, FFV_VARIABLE(v_list)->name,NO_TAG) == 0)

The include file used by the code is rather long, but the part that defines FFV_VARIABLE looks like:

#define FFV_VARIABLE(v) ( (v) ? ((VARIABLE_PTR)dll_data(v)) : NULL)

Questions: how to compile it unsing pgcc? Why does it compile ok with gcc?
Thanks
Alex

Hi Alex,

Can you preprocess the source file and post the expansion of line 39? The example is missing the defintions for VARIABLE_PTR, VARIABLE_LIST_PTR, FORMAT_PTR, and NO_TAG otherwise I’d do this myself. Also, please post the defintion of “dll_data”.

To preprocess a file, compile using the “-P” (stop after preprocessing). The processed file will be “.i”. You can also use “-E” but this redirects the output to stdout.

Line 39 should expand to something like:

if(memStrcmp(name, (VARIABLE_PTR)dll_data(v_list)->name,NO_TAG) == 0)

In order to use the member selector opterator here, dll_data must be an array of structs or unions.

  • Mat

Mat,

The output from the .i file is quite verbose, but if you feel you need it I can surely post it here.The expansion for line 39 looks like this:

if ( strcmp ( name , ( ( v_list ) ? ( ( VARIABLE_PTR ) ( ( v_list ) -> data_ptr ) ) : ( ( void * ) 0 ) ) -> name ) == 0 )

The definition for dll_data comes from this dl_lists.h file (all of it):

#ifndef DLL_DEFS
#define DLL_DEFS
typedef struct list_node		/* NODE STRUCTURE */
{
	struct	list_node *previous;		/* previous node pointer */
	struct	list_node *next;		/* next node pointer */
	void	*data_ptr;	   		/* data pointer	*/
#ifdef DLL_CHECKS_ON
	unsigned int status;
	size_t length;
#endif
} DLL_NODE, *DLL_NODE_PTR;

typedef struct {
	int fileid;
	FILE *stream;
	fpos_t pos;
	int nline;
} FILE_DLL_DATA;				

/* linked list macros */
#define dll_data(n)	((n)->data_ptr)
#define dll_next(n)	((n)->next)
#define dll_previous(n)	((n)->previous)
#define dll_first(h)	((h)->next)
#define dll_last(h)	((h)->previous)

/* Function Prototypes */
DLL_NODE_PTR dll_init(void);
DLL_NODE_PTR dll_insert(DLL_NODE_PTR, unsigned int);
DLL_NODE_PTR dll_add(DLL_NODE_PTR, unsigned int);
DLL_NODE_PTR dll_init_contiguous(void *, void *, unsigned int);
void 	     dll_delete(DLL_NODE_PTR, void (*)(void *));
int dll_free(DLL_NODE_PTR head, void (*)(void *));
#endif		/* End of DLL_DEFS */

Please tell me if you still need the .i file or the other definitions for VARIABLE_PTR, VARIABLE_LIST_PTR, FORMAT_PTR, and NO_TAG. The full code has many include files inside other include files, so these definitions are not so promptly available.

Thanks,
Alex

Hi Alex,

The way in which conditional expressions are evaluated are implimentation dependant. pgcc turns them into if/else expressions, so the line

( ( v_list ) ? ( ( VARIABLE_PTR ) ( ( v_list ) -> data_ptr ) ) : ( ( void * ) 0 ) ) -> name

will turn into

  if (v_list) {
    ( (VARIABLE_PTR)  ( ( v_list ) -> data_ptr ))->name;
  } else {
    ( ( void * ) 0 )  -> name;
 }

So pgcc is complaining that “( ( void * ) 0 )” is not a struct. To fix change your definition of FFV_VARIABLE to add “VARIABLE_PTR” before the “NULL”

#define FFV_VARIABLE(v) ( (v) ? ((VARIABLE_PTR)dll_data(v)) : (VARIABLE_PTR) NULL)

Now your void pointer will be cast to the correct data type.

Hope this helps,
Mat

Dear Mat,

That indeed solved the problem. Thank you!

Cheers,
Alex