Hi all, since I started playing around with Zend API, I thought it would
be better to start writing some small functions as practice. Then my
entire weekend became nightmare.
I've tried to add a function activated in dynamic module, and it gives a
very strange result. This function is really simple: taking an integer
as argument, returns a 'hhhh:mm:ss' format string. If additional
argument (BOOL) is set to true, then the 'hhhh' will turn to 'DD hh'.
Now, it works fine while compiled with GCC alone in standard C style,
but while working as a PHP function, the result is like this:
(!靠备h2339:44:05
(!靠备窵▒97D 11:44:05
What are the characters in front of them? Where did they come? It's
really confusing......
The original Zend style code is as follow:
ZEND_FUNCTION(cj_format_clock)
{
char res[50], myb[10];
long mys = 0;
double myd, myh, mym;
zend_bool useDay = 0;
if ( zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS()
TSRMLS_CC, "l|b", &mys, &useDay) == FAILURE )
{
php_error(E_ERROR, "Expecting cj_format_clock([(INT)seconds])",
get_active_function_name(TSRMLS_C));
return;
}
if ( mys < 0 )
{
php_error(E_ERROR, "Number of second must be a possitive integer",
get_active_function_name(TSRMLS_C));
return;
}
if ( useDay )
{
myd = mys / 86400;
mys %= 86400;
sprintf(myb, "%.0f", myd);
strcat(res, myb);
strcat(res, "D ");
}
myh = mys / 3600;
mys %= 3600;
if ( myh < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", myh);
strcat(res, myb);
strcat(res, ":");
mym = mys / 60;
mys %= 60;
if ( mym < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", mym);
strcat(res, myb);
strcat(res, ":");
if ( mys < 10 )
strcat(res, "0");
sprintf(myb, "%d", mys);
strcat(res, myb);
RETURN_STRING(res, 1);
}
Hi,
Try initializing your "res" variable first.
either:
memset(&res, 0, sizeof(res));
Or:
res[0] = 0;
Both will work, it all depends if you want to write "clean" code, of
"fast" code (and your definition of both).
I believe there are cleaner way to do what you are doing, but I'll let
that to your curiosity.
Mark
Le dimanche 16 novembre 2008 à 21:15 +0800, Chris Jiang a écrit :
Hi all, since I started playing around with Zend API, I thought it would
be better to start writing some small functions as practice. Then my
entire weekend became nightmare.I've tried to add a function activated in dynamic module, and it gives a
very strange result. This function is really simple: taking an integer
as argument, returns a 'hhhh:mm:ss' format string. If additional
argument (BOOL) is set to true, then the 'hhhh' will turn to 'DD hh'.Now, it works fine while compiled with GCC alone in standard C style,
but while working as a PHP function, the result is like this:(!靠备h2339:44:05
(!靠备窵▒97D 11:44:05What are the characters in front of them? Where did they come? It's
really confusing......The original Zend style code is as follow:
ZEND_FUNCTION(cj_format_clock)
{
char res[50], myb[10];
long mys = 0;
double myd, myh, mym;
zend_bool useDay = 0;if ( zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS()
TSRMLS_CC, "l|b", &mys, &useDay) == FAILURE )
{
php_error(E_ERROR, "Expecting cj_format_clock([(INT)seconds])",
get_active_function_name(TSRMLS_C));
return;
}if ( mys < 0 )
{
php_error(E_ERROR, "Number of second must be a possitive integer",
get_active_function_name(TSRMLS_C));
return;
}if ( useDay )
{
myd = mys / 86400;
mys %= 86400;
sprintf(myb, "%.0f", myd);
strcat(res, myb);
strcat(res, "D ");
}myh = mys / 3600;
mys %= 3600;
if ( myh < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", myh);
strcat(res, myb);strcat(res, ":");
mym = mys / 60;
mys %= 60;
if ( mym < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", mym);
strcat(res, myb);strcat(res, ":");
if ( mys < 10 )
strcat(res, "0");
sprintf(myb, "%d", mys);
strcat(res, myb);RETURN_STRING(res, 1);
}
Ah, greet appreciation! The memset() way works perfectly, but the res[0]
way didn't work.
Beside, I think you are right. Although I'm just a beginner in C
language, but from the experience of JS and PHP, also according to the
document I've been searching all the time, there should be something
related to time.h functions which might be more suitable for what I'm
doing. However, at the mean time, I'm just trying to get 'strings' to
work in C and Zend, hehe!
Still, this is a really strange experience. Where are those characters
come from? Shouldn't it be a clean array when I first created them?
Anything related to the zval structure?
Thank you again!
M. Karpelès wrote:
Hi,
Try initializing your "res" variable first.
either:
memset(&res, 0, sizeof(res));
Or:
res[0] = 0;
Both will work, it all depends if you want to write "clean" code, of
"fast" code (and your definition of both).I believe there are cleaner way to do what you are doing, but I'll let
that to your curiosity.Mark
Le dimanche 16 novembre 2008 à 21:15 +0800, Chris Jiang a écrit :
Hi all, since I started playing around with Zend API, I thought it would
be better to start writing some small functions as practice. Then my
entire weekend became nightmare.I've tried to add a function activated in dynamic module, and it gives a
very strange result. This function is really simple: taking an integer
as argument, returns a 'hhhh:mm:ss' format string. If additional
argument (BOOL) is set to true, then the 'hhhh' will turn to 'DD hh'.Now, it works fine while compiled with GCC alone in standard C style,
but while working as a PHP function, the result is like this:(!靠备h2339:44:05
(!靠备窵▒97D 11:44:05What are the characters in front of them? Where did they come? It's
really confusing......The original Zend style code is as follow:
ZEND_FUNCTION(cj_format_clock)
{
char res[50], myb[10];
long mys = 0;
double myd, myh, mym;
zend_bool useDay = 0;if ( zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS()
TSRMLS_CC, "l|b", &mys, &useDay) == FAILURE )
{
php_error(E_ERROR, "Expecting cj_format_clock([(INT)seconds])",
get_active_function_name(TSRMLS_C));
return;
}if ( mys < 0 )
{
php_error(E_ERROR, "Number of second must be a possitive integer",
get_active_function_name(TSRMLS_C));
return;
}if ( useDay )
{
myd = mys / 86400;
mys %= 86400;
sprintf(myb, "%.0f", myd);
strcat(res, myb);
strcat(res, "D ");
}myh = mys / 3600;
mys %= 3600;
if ( myh < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", myh);
strcat(res, myb);strcat(res, ":");
mym = mys / 60;
mys %= 60;
if ( mym < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", mym);
strcat(res, myb);strcat(res, ":");
if ( mys < 10 )
strcat(res, "0");
sprintf(myb, "%d", mys);
strcat(res, myb);RETURN_STRING(res, 1);
}
Hi,
Try initializing your "res" variable first.
either:
memset(&res, 0, sizeof(res));
Or:
res[0] = 0;
Both will work, it all depends if you want to write "clean" code, of
"fast" code (and your definition of both).I believe there are cleaner way to do what you are doing, but I'll let
that to your curiosity.Mark
Le dimanche 16 novembre 2008 à 21:15 +0800, Chris Jiang a écrit :
Hi all, since I started playing around with Zend API, I thought it would
be better to start writing some small functions as practice. Then my
entire weekend became nightmare.I've tried to add a function activated in dynamic module, and it gives a
very strange result. This function is really simple: taking an integer
as argument, returns a 'hhhh:mm:ss' format string. If additional
argument (BOOL) is set to true, then the 'hhhh' will turn to 'DD hh'.Now, it works fine while compiled with GCC alone in standard C style,
but while working as a PHP function, the result is like this:(!靠备h2339:44:05
(!靠备窵▒97D 11:44:05What are the characters in front of them? Where did they come? It's
really confusing......The original Zend style code is as follow:
ZEND_FUNCTION(cj_format_clock)
{
char res[50], myb[10];
long mys = 0;
double myd, myh, mym;
zend_bool useDay = 0;if ( zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS()
TSRMLS_CC, "l|b", &mys, &useDay) == FAILURE )
{
php_error(E_ERROR, "Expecting cj_format_clock([(INT)seconds])",
get_active_function_name(TSRMLS_C));
return;
}if ( mys < 0 )
{
php_error(E_ERROR, "Number of second must be a possitive integer",
get_active_function_name(TSRMLS_C));
return;
}if ( useDay )
{
myd = mys / 86400;
mys %= 86400;
sprintf(myb, "%.0f", myd);
strcat(res, myb);
strcat(res, "D ");
}myh = mys / 3600;
mys %= 3600;
if ( myh < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", myh);
strcat(res, myb);strcat(res, ":");
mym = mys / 60;
mys %= 60;
if ( mym < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", mym);
strcat(res, myb);strcat(res, ":");
if ( mys < 10 )
strcat(res, "0");
sprintf(myb, "%d", mys);
strcat(res, myb);RETURN_STRING(res, 1);
}
This is per definition: In C local variables are not initialized with anything! The weird characters you see are content from prior memory usage leftover from calls to other functions. Its just garbage. In C, local variables must always be initialized.
Uwe Schindler
thetaphi@php.net - http://www.php.net
NSAPI SAPI developer
Bremen, Germany
-----Original Message-----
From: Chris Jiang [mailto:jiangcat@gmail.com]
Sent: Sunday, November 16, 2008 2:36 PM
To: internals@lists.php.net; "M. Karpelès"
Cc: internals@lists.php.net
Subject: Re: [PHP-DEV] Can someone explain me why this happens please?Ah, greet appreciation! The memset() way works perfectly, but the res[0]
way didn't work.Beside, I think you are right. Although I'm just a beginner in C
language, but from the experience of JS and PHP, also according to the
document I've been searching all the time, there should be something
related to time.h functions which might be more suitable for what I'm
doing. However, at the mean time, I'm just trying to get 'strings' to
work in C and Zend, hehe!Still, this is a really strange experience. Where are those characters
come from? Shouldn't it be a clean array when I first created them?
Anything related to the zval structure?Thank you again!
M. Karpelès wrote:
Hi,
Try initializing your "res" variable first.
either:
memset(&res, 0, sizeof(res));
Or:
res[0] = 0;
Both will work, it all depends if you want to write "clean" code, of
"fast" code (and your definition of both).I believe there are cleaner way to do what you are doing, but I'll let
that to your curiosity.Mark
Le dimanche 16 novembre 2008 à 21:15 +0800, Chris Jiang a écrit :
Hi all, since I started playing around with Zend API, I thought it
would
be better to start writing some small functions as practice. Then my
entire weekend became nightmare.I've tried to add a function activated in dynamic module, and it gives
a
very strange result. This function is really simple: taking an integer
as argument, returns a 'hhhh:mm:ss' format string. If additional
argument (BOOL) is set to true, then the 'hhhh' will turn to 'DD hh'.Now, it works fine while compiled with GCC alone in standard C style,
but while working as a PHP function, the result is like this:(!靠备h2339:44:05
(!靠备窵▒97D 11:44:05What are the characters in front of them? Where did they come? It's
really confusing......The original Zend style code is as follow:
ZEND_FUNCTION(cj_format_clock)
{
char res[50], myb[10];
long mys = 0;
double myd, myh, mym;
zend_bool useDay = 0;if ( zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
ZEND_NUM_ARGS()
TSRMLS_CC, "l|b", &mys, &useDay) == FAILURE )
{
php_error(E_ERROR, "Expecting
cj_format_clock([(INT)seconds])",
get_active_function_name(TSRMLS_C));
return;
}if ( mys < 0 )
{
php_error(E_ERROR, "Number of second must be a possitive
integer",
get_active_function_name(TSRMLS_C));
return;
}if ( useDay )
{
myd = mys / 86400;
mys %= 86400;
sprintf(myb, "%.0f", myd);
strcat(res, myb);
strcat(res, "D ");
}myh = mys / 3600;
mys %= 3600;
if ( myh < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", myh);
strcat(res, myb);strcat(res, ":");
mym = mys / 60;
mys %= 60;
if ( mym < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", mym);
strcat(res, myb);strcat(res, ":");
if ( mys < 10 )
strcat(res, "0");
sprintf(myb, "%d", mys);
strcat(res, myb);RETURN_STRING(res, 1);
}Hi,
Try initializing your "res" variable first.
either:
memset(&res, 0, sizeof(res));
Or:
res[0] = 0;
Both will work, it all depends if you want to write "clean" code, of
"fast" code (and your definition of both).I believe there are cleaner way to do what you are doing, but I'll let
that to your curiosity.Mark
Le dimanche 16 novembre 2008 à 21:15 +0800, Chris Jiang a écrit :
Hi all, since I started playing around with Zend API, I thought it
would
be better to start writing some small functions as practice. Then my
entire weekend became nightmare.I've tried to add a function activated in dynamic module, and it gives
a
very strange result. This function is really simple: taking an integer
as argument, returns a 'hhhh:mm:ss' format string. If additional
argument (BOOL) is set to true, then the 'hhhh' will turn to 'DD hh'.Now, it works fine while compiled with GCC alone in standard C style,
but while working as a PHP function, the result is like this:(!靠备h2339:44:05
(!靠备窵▒97D 11:44:05What are the characters in front of them? Where did they come? It's
really confusing......The original Zend style code is as follow:
ZEND_FUNCTION(cj_format_clock)
{
char res[50], myb[10];
long mys = 0;
double myd, myh, mym;
zend_bool useDay = 0;if ( zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
ZEND_NUM_ARGS()
TSRMLS_CC, "l|b", &mys, &useDay) == FAILURE )
{
php_error(E_ERROR, "Expecting
cj_format_clock([(INT)seconds])",
get_active_function_name(TSRMLS_C));
return;
}if ( mys < 0 )
{
php_error(E_ERROR, "Number of second must be a possitive
integer",
get_active_function_name(TSRMLS_C));
return;
}if ( useDay )
{
myd = mys / 86400;
mys %= 86400;
sprintf(myb, "%.0f", myd);
strcat(res, myb);
strcat(res, "D ");
}myh = mys / 3600;
mys %= 3600;
if ( myh < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", myh);
strcat(res, myb);strcat(res, ":");
mym = mys / 60;
mys %= 60;
if ( mym < 10 )
strcat(res, "0");
sprintf(myb, "%.0f", mym);
strcat(res, myb);strcat(res, ":");
if ( mys < 10 )
strcat(res, "0");
sprintf(myb, "%d", mys);
strcat(res, myb);RETURN_STRING(res, 1);
}
Le dimanche 16 novembre 2008 à 21:35 +0800, Chris Jiang a écrit :
Still, this is a really strange experience. Where are those characters
come from? Shouldn't it be a clean array when I first created them?
Anything related to the zval structure?
This is not PHP-related. When you define a variable, it has no
content, you have to initialize it. The characters you got are from the
uninitialized space you used in the stack.
C won't initialize variables for you as it would be a waste of time in
the case you already initialize it with a non-NULL value.
Anyway as this is not PHP-related, I suggest this discussion to be
continued outside of the PHP internals mailing list, if you have any
question, I can probably give you some pointers to good documentation,
just need to understand what you are trying to do.
Best regards,
Mark
Ok, I see. Thank you all for replying. I guess there are a lot to be
learned for me now.
I'm actually trying to learn C and put it in use of writing PHP
extensions. Because from years of working with PHP, I start to feel that
PHP might be a bit weak for performance sensitive tasks.
Well, it's a long way ahead, and I'd better get going now. Thanks again
for the help, and I'll send more 'spam' if I've got problem with PHP and
Zend in the future. :D
M. Karpelès 写道:
Le dimanche 16 novembre 2008 à 21:35 +0800, Chris Jiang a écrit :
Still, this is a really strange experience. Where are those characters
come from? Shouldn't it be a clean array when I first created them?
Anything related to the zval structure?This is not PHP-related. When you define a variable, it has no
content, you have to initialize it. The characters you got are from the
uninitialized space you used in the stack.C won't initialize variables for you as it would be a waste of time in
the case you already initialize it with a non-NULL value.Anyway as this is not PHP-related, I suggest this discussion to be
continued outside of the PHP internals mailing list, if you have any
question, I can probably give you some pointers to good documentation,
just need to understand what you are trying to do.Best regards,
Mark