proc C should access the #temp that is nearest in terms of scope, ie, the #temp created in proc B. (Sorry, not sure if/where that may be located in the manuals; only know this is how it's always worked for me for the last umpteen years.)
ASE will actually create multiple #temp* tables in the spid's temporary database, appending each table's name with a 2-digit number representing the nesting level where the table was created (topmost level = 00).
For example:
===========================
-- to be referenced by p3
create table #temp(a int)
go
create proc p3
as
-- display all tables with name '#temp%'
-- NOTE: I only have 1 tempdb so no problems hardcoding 'tempdb' here
select id,name from tempdb..sysobjects where name like '#temp%' order by name
-- which #temp table am I accessing:
select object_id('#temp'),* from #temp
go
-- remove so p1/p2 can be created without generating an error
drop table #temp
go
create proc p2
as
create table #temp(a int)
insert #temp values (2)
exec p3
go
create proc p1
as
create table #temp(a int)
insert #temp values (1)
exec p2
go
-- recreate our topmost #temp and populate
create table #temp(a int)
go
insert #temp values (0)
go
-- run our test
exec p1
go
id name
--------- ----------------------
442475018 #temp00000180018371985 - 1st table; topmost version (nesting level 0)
602475588 #temp01000180018371985 - 2nd table; created in p1 (nesting level 1)
618475645 #temp02000180018371985 - 3rd table; created in p2 (nesting level 2)
a
--------- -----------
618475645 2 - p2's table (#temp02% w/ a=2)
===========================
NOTE: The above runs as shown in ASE 12.5.4 and 15.0.3 (and I want to say I recall it ran this way in 11.x, too).
NOTE: I'm not using DNR (not available prior to ASE 15.5)