Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:22355 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 90900 invoked by uid 1010); 13 Mar 2006 01:46:13 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 90863 invoked from network); 13 Mar 2006 01:46:12 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 13 Mar 2006 01:46:12 -0000 X-Host-Fingerprint: 194.73.73.211 c2bthomr03.btconnect.com FreeBSD 4.7-5.2 (or MacOS X 10.2-10.3) (2) Received: from ([194.73.73.211:9194] helo=c2bthomr03.btconnect.com) by pb1.pair.com (ecelerity 2.0 beta r(6323M)) with SMTP id E1/00-55982-2EEC4144 for ; Sun, 12 Mar 2006 20:46:10 -0500 Received: from va517slx (host81-134-174-53.in-addr.btopenworld.com [81.134.174.53]) by c2bthomr03.btconnect.com (MOS 3.5.9-GR) with ESMTP id ELF01667; Mon, 13 Mar 2006 01:45:58 GMT To: internals@lists.php.net Date: Mon, 13 Mar 2006 01:46:03 +0000 User-Agent: KMail/1.8 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-ID: <200603130146.03791.an.dromeda@btconnect.com> Subject: INFO: INIT_CLASS_ENTRY fails on various char entry formats From: an.dromeda@btconnect.com I was surprised to find that my class entry failed when I tried to pass the class name as a parameter. Two common styles (char *myclassname = "myclass"; and (over-buffered) char myclassname[100] = "myclass";) both fail with INIT_CLASS_ENTRY for a reason that becomes apparent when you look at the source (interesting experience, having the source available!). INIT_CLASS_ENTRY determines the classname length by sizeof(myclassname) not strlen(myclassname), so the former char* returns 4, being the size of a pointer, and the latter returns 100, being the size of the buffer, neither being then intended reasonable size of the name as would have been determined by strlen, here 7 ("myclass"). Consequently, a call to instantiate 'new myclass()' fails, with no such class name registered. Maybe that's 'obvious' and I should have known better, but both buffers and static (?) strings I thought were 'reasonable' and in normal use, so I thought I'd flag the issue. (Interestingly, in zend_API.c, ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC) receives a char* for class_name which it passes to INIT_CLASS_ENTRY, presumably without ill-effect, and despite the issue above...) Am I missing something, or is that simply a behaviour that's a) intentional, or b) understood and just needs to be worked around. Conundrum: I had assumed that to resolve this, I may need to set up an 'emalloc()' of the precise length required, but in fact this still does not resolve the issue, as the char* returned by the emalloc will be sizeof() = 4, whatever the string. Is there no way therefore to pass a variable length classname to a dynamic class creation routine? Seems a little unlikely, but I can't see it in light of the above. Guess I can ignore the INIT_CLASS_ENTRY macro, or let it run and then post-assign the classname with appropriate length based on strlen() or std::string.length(). Just a thought. // Various formats tried: // char phpclassname[50] = "minicooper"; // char *phpclassname = "minicooper"; char phpclassname[11] = "minicooper"; // this works - exact + 1 for zero // char phpclassname[10] = "minicooper"; // this fails - insufficient bytes (to include terminating zero) // char phpclassname[12] = "minicooper"; // this fails - sizeof is 'too big' (one spare byte - buffer must be 'exact' // char phpclassname[50] = "minicooper"; // this fails - ditto - too big // phpclassname[10] = '\0'; // this does not resolve 'too big' buffers // string spcname("minicooper"); // this does not work // Calls based on the above, as appropriate // INIT_CLASS_ENTRY(ce, spcname.c_str(), minicooper_class_functions); INIT_CLASS_ENTRY(ce, phpclassname, minicooper_class_functions); // INIT_CLASS_ENTRY(ce, "minicooper", minicooper_class_functions);