473,750 Members | 6,334 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Handling 'initializer element not constant' error

Hi,

I had some C code written which initialized a global variable as:

FILE *yyerfp = stdout;

This used to work fine in older versions of gcc. Now, when I tried to
compile this code (with gcc 3.2.3),
I got errors like:

.../Include/Message.h:42: initializer element is not constant

I looked around the www and found that stdin/stdout/stderr are *not*
made const in the newer
versions of gcc.

As a work-around, I thought of this:

FILE *yyerfp; // Uninitialized global

// Initialize it in a separate function
void initializeGloba ls( void )
{
yyerfp = stdout;
}

int main( ... )
{
// Initialize the global before doing anything else
initializeGloba ls();
...
// Do other things
}

But, this code will also be compiled into a shared object, dynamically
loadable from other
languages such as perl etc. and I do not want to change the API
interface there. If I follow
this approach, I also have to add the initializeGloba ls() call in
every perl program which uses
this library.

What is the best way of solving this problem?

Thanks
Gowtham
Jun 27 '08 #1
16 2776
Hi

On May 7, 3:14 pm, Gowtham <gowthamgowt... @gmail.comwrote :
I had some C code written which initialized a global variable as:

FILE *yyerfp = stdout;
...
But, this code will also be compiled into a shared object
...
What is the best way of solving this problem?
The correct and best way to solve this problem is to remember that
library functions should not write to the standard streams.

Imagine that stdin, stdout and stderr are local variables within
main(). Any library function that needs to write to a file should
take a pointer to one as an argument. The author of main() can then
pass stdout *if* they give you permission to write to it.

This makes your code more modular and easier to reuse, it makes it
easier to read and debug because you can follow information flow from
the prototypes only, and it also stops developers who use your library
from pulling their hair out because you are printing to streams that
you shouldn't, not following their message conventions or corrupting
their output completely.

viza
Jun 27 '08 #2
viza wrote:
) Hi
)
) On May 7, 3:14 pm, Gowtham <gowthamgowt... @gmail.comwrote :
)
)I had some C code written which initialized a global variable as:
)>
)FILE *yyerfp = stdout;
)...
)But, this code will also be compiled into a shared object
)...
)What is the best way of solving this problem?
)
) The correct and best way to solve this problem is to remember that
) library functions should not write to the standard streams.
)
) Imagine that stdin, stdout and stderr are local variables within
) main(). Any library function that needs to write to a file should
) take a pointer to one as an argument. The author of main() can then
) pass stdout *if* they give you permission to write to it.
)
) This makes your code more modular and easier to reuse, it makes it
) easier to read and debug because you can follow information flow from
) the prototypes only, and it also stops developers who use your library
) from pulling their hair out because you are printing to streams that
) you shouldn't, not following their message conventions or corrupting
) their output completely.

There was a discussion recently where someone was trying all kinds of hacks
and workarounds to capture the output from a library, because he did not
want it to go to stdout.

I would consider that a very good example of why your advice is good
advice. To the OP: libraries shouldn't be using stdout, and certainly
not hardwired.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
Jun 27 '08 #3
In article <sl************ ********@snail. stack.nl>,
Willem <wi****@stack.n lwrote:
>)FILE *yyerfp = stdout;
>I would consider that a very good example of why your advice is good
advice. To the OP: libraries shouldn't be using stdout, and certainly
not hardwired.
In general I agree.

But the fact that he's using it to initialise a variable strongly
suggests that it is *not* hardwired, but just a default. If the user
wasn't supposed to be able to change it, the OP could just use stdio
instead of yyerfp.

Assuming the OP can change the code of the library, he could
initialise yyerfp to NULL and replace all the uses of it with

(yyerfp ? yyerfp : stdout)

It's a pity there isn't a standard way to get initialisation code run.

-- Richard
--
:wq
Jun 27 '08 #4
On May 7, 8:01 pm, rich...@cogsci. ed.ac.uk (Richard Tobin) wrote:
In article <slrng23i52.1aj 2.wil...@snail. stack.nl>,

Willem <wil...@stack.n lwrote:
)FILE *yyerfp = stdout;
I would consider that a very good example of why your advice is good
advice. To the OP: libraries shouldn't be using stdout, and certainly
not hardwired.

In general I agree.

But the fact that he's using it to initialise a variable strongly
suggests that it is *not* hardwired, but just a default. If the user
wasn't supposed to be able to change it, the OP could just use stdio
instead of yyerfp.

Assuming the OP can change the code of the library, he could
initialise yyerfp to NULL and replace all the uses of it with

(yyerfp ? yyerfp : stdout)
Slightly better way:

FILE *yyerfp_;
/* ... */
#define yyerfp (yyerfp ? yyerfp : stdout)
It's a pity there isn't a standard way to get initialisation code run.
I don't think it's that much of a problem. Well-designed code wouldn't
use global variables. (with few exceptions such as errno)
Jun 27 '08 #5
On May 7, 8:29 pm, vipps...@gmail. com wrote:
On May 7, 8:01 pm, rich...@cogsci. ed.ac.uk (Richard Tobin) wrote:
In article <slrng23i52.1aj 2.wil...@snail. stack.nl>,
Willem <wil...@stack.n lwrote:
>)FILE *yyerfp = stdout;
>I would consider that a very good example of why your advice is good
>advice. To the OP: libraries shouldn't be using stdout, and certainly
>not hardwired.
In general I agree.
But the fact that he's using it to initialise a variable strongly
suggests that it is *not* hardwired, but just a default. If the user
wasn't supposed to be able to change it, the OP could just use stdio
instead of yyerfp.
Assuming the OP can change the code of the library, he could
initialise yyerfp to NULL and replace all the uses of it with
(yyerfp ? yyerfp : stdout)

Slightly better way:

FILE *yyerfp_;
/* ... */
#define yyerfp (yyerfp ? yyerfp : stdout)
Sigh, what's up with all these mistakes lately...
#define yyerfp (yyerfp_ ? yyerfp_ : stdout)
It's a pity there isn't a standard way to get initialisation code run.

I don't think it's that much of a problem. Well-designed code wouldn't
use global variables. (with few exceptions such as errno)
Jun 27 '08 #6
In article <9c************ *************** *******@25g2000 hsx.googlegroup s.com>,
<vi******@gmail .comwrote:
>It's a pity there isn't a standard way to get initialisation code run.
>I don't think it's that much of a problem. Well-designed code wouldn't
use global variables.
You're letting a slogan override your common sense. There are many
cases of global variables that are completely reasonable.

For example, I want to convert between ISO Latin-5 (an 8-bit character
set) and Unicode code points (which can be considered to have 2^16
characters for this purpose). To do this, I have a table of 256
entries mapping Latin-5 to Unicode, and I want to build the reverse
table at start-up. These two global variables, latin_5_to_unic ode and
unicode_to_lati n_5, have no objectionable properties.
(with few exceptions such as errno)
Not a reasonable example at all. It was adequate 20 years ago, but
today is a fine example of the problems with global variables.

-- Richard
--
:wq
Jun 27 '08 #7
ri*****@cogsci. ed.ac.uk (Richard Tobin) writes:
In article <9c************ *************** *******@25g2000 hsx.googlegroup s.com>,
<vi******@gmail .comwrote:
>>It's a pity there isn't a standard way to get initialisation code run.
>>I don't think it's that much of a problem. Well-designed code wouldn't
use global variables.

You're letting a slogan override your common sense. There are many
cases of global variables that are completely reasonable.

For example, I want to convert between ISO Latin-5 (an 8-bit character
set) and Unicode code points (which can be considered to have 2^16
characters for this purpose). To do this, I have a table of 256
entries mapping Latin-5 to Unicode, and I want to build the reverse
table at start-up. These two global variables, latin_5_to_unic ode and
unicode_to_lati n_5, have no objectionable properties.
[...]

Without resurrecting the unresolved argument over the definition of
"variable" I'll note that your global objects latin_5_to_unic ode and
unicode_to_lati n_5 presumably do not vary once they've been
initialized. Global objects whose values are never modified during
program execution are less problematic than global objects whose
values can vary over time. ("Global" here refers to file scope and
static duration, more or less.)

--
Keith Thompson (The_Other_Keit h) <ks***@mib.or g>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #8
On May 7, 10:21 pm, rich...@cogsci. ed.ac.uk (Richard Tobin) wrote:
In article <9c2b13d5-b18d-498e-aec8-d239d0bb3...@25 g2000hsx.google groups.com>,

<vipps...@gmail .comwrote:
It's a pity there isn't a standard way to get initialisation code run.
I don't think it's that much of a problem. Well-designed code wouldn't
use global variables.

You're letting a slogan override your common sense. There are many
cases of global variables that are completely reasonable.

For example, I want to convert between ISO Latin-5 (an 8-bit character
set) and Unicode code points (which can be considered to have 2^16
characters for this purpose). To do this, I have a table of 256
entries mapping Latin-5 to Unicode, and I want to build the reverse
table at start-up. These two global variables, latin_5_to_unic ode and
unicode_to_lati n_5, have no objectionable properties.
Ah, indeed. Another example would be a table for all the is*()
functions in <ctype.h>, in a C lib implementation.
I just try to avoid global variables, because they can lead to a bad
design, when there's a better option available.
(with few exceptions such as errno)

Not a reasonable example at all. It was adequate 20 years ago, but
today is a fine example of the problems with global variables.
OK, you are right. I can see what you mean, one example would be with
threads I suppose.
I have not read much on alternative solutions to errno in C, so is
there a better solution?
Returning the error code is not possible (like pthreads) and an extra
parameter to every function that can fail would be quite annoying.
Jun 27 '08 #9
Gowtham wrote:
Hi,

I had some C code written which initialized a global variable as:

FILE *yyerfp = stdout;
In C, stdin, stdout and stderr are macros. They needn't be
constant expressions.
This used to work fine in older versions of gcc. Now, when I
tried to compile this code (with gcc 3.2.3),
I got errors like:

../Include/Message.h:42: initializer element is not constant
That is your error, not glibc's.
I looked around the www and found that stdin/stdout/stderr
are *not* made const in the newer versions of gcc.
They don't need to be.
As a work-around, I thought of this:

FILE *yyerfp; // Uninitialized global
Actually, it's zero initialised (to a null pointer).
// Initialize it in a separate function
void initializeGloba ls( void )
{
yyerfp = stdout;
}

int main( ... )
{
// Initialize the global before doing anything else
initializeGloba ls();
...
// Do other things
}

But, this code will also be compiled into a shared object,
dynamically loadable from other languages such as perl etc.
and I do not want to change the API interface there.
Fine, but in a sense, it's your interface that is a problem.
If I follow this approach, I also have to add the
initializeGloba ls() call in every perl program which uses
this library.
Replace it with a macro/function like...

#define YYERFP \
(yyerfp ? yyerfp : (yyerfp = stdout))

int library_foo()
{
FILE *fp = YYERFP;
...
}

<OTThe other choice of course is C++ </OT>
What is the best way of solving this problem?
Don't make libraries dependant on non-zero initialisation of
static variables.

--
Peter
Jun 27 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
19567
by: Todd Nathan | last post by:
Hi. have this code and compiler problem. GCC 2.95.3, BeOS, error "initializer element is not constant" #ifdef FILEIO { static struct { char *sfn; FILE *sfd; } stdfiles = {
2
1963
by: Mantorok Redgormor | last post by:
struct mystruct { int a; int b; }; struct mystruct x = { 10, 10 }, y = x; What section in the standard says that y needs a constant? And why can't it resolve x so that y can have a copy of its values?
3
2457
by: Levi Campbell | last post by:
Hi, I'm trying to debug an app someone else wrote called eMixer. Here's the log contents: cc -O3 -funroll-loops -c -o main.o main.c cc -O3 -funroll-loops -c -o nctgui.o nctgui.c cc -O3 -funroll-loops -c -o mixer.o mixer.c mixer.c: In function `open_soundcard_alsa':
3
1393
by: vib | last post by:
Hi there, I wish to get some advice on the problem I face in initializing a table. Here is the code. I've an array of strings, ptrNameString . I want to initialize a table, mySoftKeyTable with some contents of the string from the array. This initialization is not in any function, but rather outside of any function. However, the compiler complaints, the related lines( L1, L2, L3, L4) of "Initializer element is not constant". I
5
7881
by: fred | last post by:
Hi, Can someone explain me why gcc-4.0 gives me the 'Initializer element is not constant' error with this code ? Everything seems to be constant here... #include <stdio.h> typedef struct { int a; int b;} t; int main(int argc, char** argv) {
7
10202
by: Paul Edwards | last post by:
On ecgs (gcc) 2.91.57 and on gcc 3.2.3 I am getting the error "initializer element is not constant" on the below code. The code compiles fine with other compilers I have. Is this valid C89 code? extern int *b; int *a = b; int main(void)
1
1811
varuns
by: varuns | last post by:
hi i m stuck while compiling my code for generating bindings for c code to be accessible from python i have read the ext.pdf available at python.org, and i think i have done every thing right. But while compilation an error message is displayed demobox.c:495: error: initializer element is not constant demobox.c:495: error: (near initialization for `_PyDemoBox_methods.ml_meth') ......
1
4117
varuns
by: varuns | last post by:
hi i m stuck while compiling my code for generating bindings for c code to be accessible from python i have read the ext.pdf available at python.org, and i think i have done every thing right. But while compilation an error message is displayed demobox.c:495: error: initializer element is not constant demobox.c:495: error: (near initialization for `_PyDemoBox_methods.ml_meth')
2
5000
by: hankypan1 | last post by:
Hi All, I need a tree data structure for my application. It is the non - cyclic simple tree where i can have any number of children node and each child can recursively become a sub tree like a normal tree. Now the thing is i can popullate my tree at compile time like a global data. Since i know my tree definition at compile time, instead of using pointers to point to siblings or child nodes, i am planning to use the array
0
9004
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9587
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9401
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9260
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6818
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4718
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4896
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2812
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2229
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.