[Prev][Next][Index]

scanf return value bug in pC++



I wrote:

	> P.S. Once we are talking about fscanf... Did anybody react to my
	>    note a couple weeks ago to the effect that the return value
	>    of pC++ fscanf is garbage, rather than the number of items read?

Shelby wrote:

|This also has to do with ScanBcast.  Remember if scanf is called in
|the main thread (main and other functions that are not methods of collection
|nor methods of element) only processor zero calls scanf and the return
|value is broadcast to all other processors.  If ScanBcast does not do
|that correctly you get the garbage.  

No, ScanBcast is not involved here. It is the manner in which the 
pC++ preprocessor expands scanf() that matters:

The existing precompiler expands the pC++ code

	int a;					// 1
	fscanf(f, fmt, &a);			// 2

into the following segment of temp.C:

	pcxx_scanf1(f, fmt, &a);		// 2a

, where pcxx_scanf1 is defined as follows:

int  pcxx_scanf1(FILE *pCar_0, char *pCar_1, int *pCar_2){	// 3
	if (pcxx_NodeNumber() == 0) 				// 4
	{							// 5
		fscanf(pCar_0, pCar_1, pCar_2);			// 6
	}							// 7
	return pcxx_ScanBcast(pCar_1, 1, 0, 1, pCar_2);		// 8
}								// 9

The return value of pcxx_scanf1, therefore, is that of pcxx_ScanBcast,
rather than that of the actual fscanf in line 6.

The correct way to implement fscanf is to make the pC++ preprocessor
produce pcxx_scanf1 of the following kind:

int  pcxx_scanf1(FILE *pCar_0, char *pCar_1, int *pCar_2){	
	int rv = 0;
	if (pcxx_NodeNumber() == 0) 	{
	   rv = fscanf(pCar_0, pCar_1, pCar_2);
	}
	pcxx_ScanBcast(pCar_1, 1, 0, 1, pCar_2);
	pcxx_BroadcastBytes(pcxx_NodeNumber(), sizeof(int), (void *)&rv);
 	return rv;
}


	--Vladimir