From SC22WG14-request@dkuug.dk Sat Feb 25 09:52:45 1995 Return-Path: Received: from dkuug.dk ([193.88.44.89]) by dmk.com (4.1/SMI-4.1) id AA03739; Sat, 25 Feb 95 09:52:34 MST Errors-To: SC22WG14-request@dkuug.dk Received: by dkuug.dk id AA10328 (5.65c8/IDA-1.4.4j for SC22WG14-list); Sat, 25 Feb 1995 14:18:43 +0100 Message-Id: <199502251318.AA10328@dkuug.dk> From: drt@wcwcen.wf.com (David Tribble) X-Sequence: SC22WG14@dkuug.dk 1038 Errors-To: SC22WG14-request@dkuug.dk Subject: (SC22WG14.1038) __func proposal, vs 2 To: SC22WG14@dkuug.dk (ANSI/ISO C Committee) Date: Fri, 24 Feb 1995 23:59:21 -0600 (CST) X-Mailer: ELM [version 2.4 PL21] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Length: 10645 X-Charset: ASCII X-Char-Esc: 29 Status: RO ======================= Cover sheet starts here ============ Document Number: WG14 N___/X3J11 __-___ C9X Revision Proposal ===================== Title: Addition of predefined identifier "__func". Author: David R. Tribble Author Affiliation: (Self) Postal Address: ******************** E-mail Address: dtribble@technologist.com Telephone Number: *************** Fax Number: (None) Sponsor: __________________________________________________ Date: 1995-02-25 Proposal Category: __ Editorial change/non-normative contribution __ Correction X_ New feature __ Addition to obsolescent feature list __ Addition to Future Directions __ Other (please specify) _____________________________ Area of Standard Affected: __ Environment X_ Language __ Preprocessor __ Library __ Macro/typedef/tag name __ Function __ Header __ Other (please specify) _____________________________ Prior Art: I think this was implemented by Aztec C some years ago. GNU C currently uses "__FUNCTION__" and Metaware uses "__function()". Target Audience: Programmers using debugging statements. Related Documents (if any): (None) Proposal Attached: X_ Yes __ No, but what's your interest? Abstract: The use of the predefined identifier "__func" allows programmers to specify the name of the enclosing function in debugging statements. It also may be used by the "assert()" macro. ======================= Cover sheet ends here ============== Proposal: Problem Statement: Programmers who use debugging statements often use the "__LINE__" and "__FILE__" predefined macro names ([6.8.8]). However, displaying the name of the function that contains a given debugging statement is not as easy. Typically, programmers have to add explicit strings to their debugging statements (which are typically calls to "printf()"). This leads to clutter and wasted data space. It also leads to confusion if function names are changed or function code is duplicated, and the programmer, in his haste, forgets to change the affected debugging statements. Conceptual Model: The addition of the predefined identifier "__func" would remedy this situation. "__func" is a predefined identifier that encodes the name of the enclosing function. "__func" is especially useful when used by debugging macros. Syntax and Semantics: The identifier "__func" is recognized by the translator as a predefined identifier. It is defined with a type and value as if the following declaration had been inserted after the opening brace of the function body: static char __func[] = "function_name"; Its value is a null-terminated string containing the name of the enclosing function. Its size is the length of the function's name plus a terminating null character. "__func" is an encoding of the function name as represented within the source character set, appropriately translated to characters within the execution character set [5.2.1]. The value of "__func" is the unadorned name of the enclosing function, without extraneous linkage characters (such as leading underscores) or trailing parentheses. For example, consider the fragment: #include int fx() { printf("%s\n", __func); ... } Whenever function "fx()" is called, its name is printed to the standard output: fx "__func" can also be used by the "assert()" macro (defined in ), allowing the name of the enclosing function to be printed in addition to the source file and line number. Section [7.2.1.1] would be amended to read: ... When it is executed, if `expression' is false ..., the `assert' macro writes information about the particular call that failed (including the text of the argument, the name of the source file, the source line number, and the name of the function containing the call -- the latter are respectively the values of the preprocessing macros `__FILE__' and `__LINE__' and the reserved identifier `__func') on the standard error file in an implementation- defined format(*). ... (*)Footnote: The message written may be of the form: Assertion failed: *expression*, function *abc*, file *xyz*, line *nnn* Operations can be performed upon "__func" as if it were a variable of type "array of char". In particular, these operations may be performed: & __func Addressing. Evaluates to a pointer of type "pointer to array of char". * __func Indirection. Evaluates to the first character of the function's name. __func[i] Subscripting. Evaluates to a character of the function's name. Note that "__func[strlen(__func)]" is a null character. f(__func) Function argument. When passed as an argument to a function, "__func" evaluates to a pointer of type "pointer to char" which points to the first character of the function's name. sizeof(__func) Evaluates to the length of "__func", which is the number of characters in the enclosing function's name plus a terminating null character. Other operations include pointer arithmetic ("+" and "-") and relational operators ("==", "!=", ">", ">=", "<", "<="). Given that two functions are called from the same function and are passed "__func" as an argument, whether or not they receive identical pointer values is implementation defined. The "sizeof" operator evaluates "__func" as if it were the size of a character array rather than the size of a character pointer. This means that the following expression is always true: strlen(__func) + 1 == sizeof(__func) Rationale: The use of the predefined "__func" identifier allows the programmer to use debugging statements of a more informatory nature, specifically, to indicate a particular function of interest. This is especially useful for fatal errors and ``should not occur'' conditions that produce warnings for the end user. (Well, not for the end user per se, but for technical support personnel rendering aid to an end user who encounters such a warning.) "__func" can also be used within debugging macros in order to keep track of things like the function calling stack, etc. Constraints: Unlike the "__FILE__" identifier, the "__func" name cannot be interpreted by most compilers during the preprocessing phases of translation (phases 1 through 4 [5.1.1.2]), but must be dealt with during the syntactical parsing phase (phase 7 [5.1.1.2]). (This is a situation similar to that of the "sizeof" operator.) "__func" is treated as a predefined variable name whose scope is local to each function. The "__func" identifier is defined only within function definitions (i.e., within the *compound-statement* comprising the body of a function [6.7.1]), and is undefined outside of function definitions. If this is not acceptable, then consider: The "__func" identifier is defined outside of function bodies as if the following definition were inserted at the beginning of the source file: static char __func[] = ""; [6.1.2.1] defines the kinds of scopes for identifiers: `function', `file', `block', and `function prototype'. The "__func" identifier, as defined up to this point, does not seem to qualify for any of these, but comes closest to `function' or `block' scope. Perhaps "__func" should be defined to have `block' scope, meaning that, in addition to being visible within the braces of a function body *compound-statement*, it is also visible following the opening parenthese of the function parameter declarations. Alternately, "__func" could have `function' scope, which is the kind of scope that only a statement label has. [7.1.3] states that implementations may reserve any identifier beginning with two underscores for any use. The name "__func" is reserved by the implementation, and as such may not be redefined or redeclared. This includes redeclaration as a variable, function, enumeration constant, statement label, typedef name, struct tag, union tag, or enum tag. It may, however, be #defined as a preprocessor macro. (The issue of whether a predefined identifier or keyword may be #defined does not seem to be explicitly covered in the ANSI/ISO specification; it appears to imply that this is legal.) Implementation Issues: The simplest way to implement "__func" is for the compiler to define a static variable (or constant) local to each function, which contains the name of the function. Each instance of "__func" within the body of the function is semantically equivalent to a reference to this variable. A possible optimization is to only generate data for such a variable for a given function only if "__func" is actually referenced within the function. One way to implement "__func" during the syntactic parsing phase is to treat it as a reserved keyword. This is fine, as long as the semantics stated above are adhered to. Language Compatibility Issues: This feature may also be considered for adoption by the ISO/ANSI C++ committee. Since operators may be redefined (overloaded) as functions, "__func" would be defined for those such functions as well. Since a C++ function has more information that uniquely identifies it than a C function (because a function may be a member function of a class, or it may be overloaded with different parameter types), additional predefined names may be implemented for C++, such as: "__parms" A string containing the parameter (prototype) information for the enclosing function. "__class" A string containing the name of the function's parent class, if the function were a member function. Future Considerations: It would be cleaner to define "__func" as being "const". The reason it is not "const" in this proposal is so that it more closely resembles a string constant, and currently C does not define string constants to be "const". (I suppose that this is because string constants can be passed to user-defined functions without requiring the user to define the functions as taking "const" parameters.) This of course, allows for the possibility that functions may modify the contents of "__func", just as they can modify the contents of string constants today. ====================== End of Proposal =====================