I saw the problem mainly in large code with interrupts. If one wants to use a variable inside the interrupt, this must be new. But, if for every task we assign a new variable, at the end we may have a lots that are really not necessary and most of them used once.
This is new to me - I've not come across this anomally/limitation/requirement before.

I write code in a very structured way... it doesn't mean it's the RIGHT way, it just happens to work for me.

1. At the very top I have the PIC Definitions/Configurations
2. Next I have all the Hardware Assignments and Pin Definitions, LCD and all other Defines.
3. Then EEPROM Data Statements
4. Then RAM Definitions
5. Then Constant Definitions
6. Here sits a jump to step 10.
7. Assembler Routines
8. Interrupt Routines
9. Subroutines
10. Hardware and Register Initialisation sequences
11. Main Program Loop

Wherever possible, Variables, Definitions, Subroutines etc are all in Alphabetical order within their own sections (makes them easy to find subsequently).

The variables (for example at step 4) are all in one spot... if I need Bits, then I define a Byte or a Word and sub-define that into bits.... variables that are used and reused many times throughout the program (like intermediate working variables) are defined to sit in Bank0 (it makes for considerably smaller code)...

Here is a typical example of (a few) variable definitions in a (large) program...

Code:
	SystemError var Byte Bank0			' Hardware Fatal Error Flags
		Tamper var SystemError.0		' 	Main CPU Anti-Tamper
		I2CError var SystemError.1		' 	I2C Bus Failure
		I2CVersion var SystemError.2		' 	EEPROM Incompatible
		I2CTimeout var SystemError.3		' 	I2C Bus Timeout
		I2CDevFail var SystemError.4		' 	I2C Device Failure
							' 	SystemError.5 - Unused - Reserved
							' 	SystemError.6 - Unused - Reserved
							' 	SystemError.7 - Unused - Reserved
	SystemFlags var Byte 				' System Operational Flags
							'	0=Unused
							' 	1=Unused
							'	2=Unused
							'	3=Unused
		UECursor var SystemFlags.4		'	4=User-Entry Field Cursor (0=Invisible, 1=Visible)
		UEEntry var SystemFlags.5		'	5=User-Entry (0=NOT Permitted, 1=Permitted)
		UESecure var SystemFlags.6		'	6=User-Entry Security (0=Unsecure 1=Secure)
							' 	7=Unused
	TempA var Byte					' Temporary Storage Variable
		TempBitA var TempA.0			' 	Just a Temporary Bit
	UEData var Byte	Bank0				' User-Entry EEPROM Data to be Loaded
	UEDataReference var Byte			' User-Entry EEPROM Data Reference
	UEDisplay var Byte				' User-Entry EEPROM Data being Referenced
	UELen var Byte					' User-Entry Field Length (0-16 chars long)
	UEMax var Byte					' User-Entry Maximum Field Entry Value
	UEMin var Byte					' User-Entry Minimum Field Entry Value
	UEPos var Byte					' User-Entry Current Position in Field (0-15)
	UEReference var Byte				' User-Entry Display Reference Pointer
	UETemp var Byte					' User-Entry Temporary Counter
	UETimeOut var Byte Bank0			' User-Entry Keyboard TimeOut Counter
	UEType var Byte	Bank0				' User-Entry Field Type
						  	'	 0=Alphanumeric
							'	 1=LCD Contrast Setting
							'	 2=LCD BackLight Setting
							'	 3=Idiot Selection (eg Yes/No)
							'	 4=Idiot Selection with Reset (eg Hours Counters)
							'	 5=Idiot Selection with Erase (eg Erase Event Log)
							'	 6=Date & Time Entry & Validation
							'	 7=Option Selecting Off/On/Auto Modes
							'	10=Numeric (0-255) c/w leading Blank Suppression
							'	11=Numeric (0.0-25.5) c/w leading Blank Suppression
							' 	2x=Option with Menu Skip (preset to x)
							' 	3x=Option with individual x-Bit manipulation
	XDataAddress var Word Bank0			' External EEPROM 16-bit Address
As you can see, there's noting clever here - it's just all arranged logically, all placed in one section, all documented and done to be easilly maintained.