Re: Making a struct field constant, when this struct is imported to a particular Cpp files

2009-11-12 Thread Axel Freyn
Hi Ansis,

first: you should use gcc-h...@gcc.gnu.org for questions like this...


On Thu, Nov 12, 2009 at 05:44:58AM -0800, ansis atteka wrote:
> I have a struct in a header file. And I would like to have some of this
> struct member fields to be constant, in case if this header file is included
> from some particular Cpp files. Motivation for this is to avoid some silly
> programmer errors by accidentally writing to this variable, when developer
> is not supposed to do that. I guess that it is possible to catch these
> errors already at the compile time with a const keyword.
> 
> I already have approach, but I am not quite sure whether it is
> safe(especially regarding the compiler optimizations). Below are uplaoded
> files.
> 
> In this case util.cpp is not allowed to edit S.y contents, while rw.cpp is
> allowed to do that. File h.hpp contains the struct which is customized at
> the preprocessor execution time by looking at the READONLY define.
> 
> If this is not safe, are there any other approaches? I am afraid that
> compiler might optimize out something. Assumption is that other threads will
> not touch this member. 
> 
> Regards,
> Ansis
> 
> http://old.nabble.com/file/p26318895/Makefile Makefile 
> http://old.nabble.com/file/p26318895/rw.cpp rw.cpp 
> http://old.nabble.com/file/p26318895/h.hpp h.hpp 
> http://old.nabble.com/file/p26318895/util.cpp util.cpp 
> http://old.nabble.com/file/p26318895/util.hpp util.hpp 
> 
Yes, this approach is save. However, some minor remarks:

 - I'm not completely sure whether the position of "-DONLY_READ" is
   important for some versions of gcc ??? - it is safer, when you write
   it as argument before the first file:
   g++ -O3 -DONLY_READ -c util.cpp -o util.o 


 - instead of using "-DONLY_READ" in the makefile it might be easier to
   use "#define ONLY_READ" inside the cpp-File - before including h.hpp:

   #define ONLY_READ
   #include "util.hpp"

   That creates exactly the same code.

 - The code might be easier to understand if you write:
 ONLY_READ int *y;
   instead of 
 #ifdef ONLY_READ
const int * y;
 #endif
 #ifndef ONLY_READ
int * y;
 #endif
   inside h.hpp, and
   "#define ONLY_READ const"
   in all cpp-Files where you want it to be constant (util.cpp)
   and
   "#define ONLY_READ "
   in all cpp-Files, where you want read-access (rw.cpp). These defines
   have to be before the #include-Command.

 - if you use "ONLY_READ int *y;", you can also try
   
   #ifndef ONLY_READ
   #define ONLY_READ
   #endif
   ONLY_READ int *y;
   
   in the header-file h.hpp. This allows to include without "#define
   ONLY_READ":
   - if "ONLY_READ" is not defined, you get read-Access
   - if "ONLY_READ" is defined as "const", you have constant access.


Axel  



Re: Possible bug: Template name lookup & overloaded functions.

2010-01-18 Thread Axel Freyn
Hi
On Mon, Jan 18, 2010 at 10:37:34PM +1300, Simon Hill wrote:
> http://www.gamedev.net/community/forums/topic.asp?topic_id=559287
> 
> SOURCE
> 
> template 
> void foo(pTYPE arg)
>   { arg.nid(); }
> 
> template 
> void bar()
>   {
> pTYPE var;
> foo(var);
>   }
> 
> void foo(int)
>   {}
> 
> int main()
>   {
> int i;
> foo(i); // OK: Resolves foo(int).
> bar(); // ERROR: Fails to resolve foo(int).
>   }
> ===
> 
> It seems to me now that this is a bug with GCC.
> Can someone confirm this please?
Well, I think g++ behaves correctly. As I understand the standard,
the normal function foo(int) can't be used in the template "bar",
because it is only declared afterwards. In "main", when foo is called
directly, that's no problem: there, foo and foo(int) are both
declared already. If you write:
te 
void foo(pTYPE arg)
  { arg.nid(); }

void foo(int)
  {}

template 
void bar()
  {
pTYPE var;
foo(var);
  }

int main()
  {
int i;
foo(i);
bar();
  }

it compiles fine for me. 

However, I'm not absolutely sure what the "correct" behaviour according
to the C++-standard would be.

Axel


Re: Gprof can account for less than 1/3 of execution time?!?!

2010-02-22 Thread Axel Freyn
Hi Jon,
On Mon, Feb 22, 2010 at 08:43:31AM -0600, Jon Turner wrote:
> You're not listening. I am using -pg and the program is statically
> linked. The concern I am raising is not about the function counting,
> but the reported running times, which are determined by sampling
> (read the gprof manual, if this is news to you).
>
> In this case, the mcount overhead cannot account for the discrepancy,
> since that would cause gprof to OVER-estimate the run time, while
> in this case it is UNDER-estimating. It's missing about 70% of the
> actual running time in the program.

Well, іn fact I expect gprof to UNDER-estimate the runtime: The
processor needs time in order to do the profiling (count, how often a
function was called from which function; measure the times, ...) Now:

 - the external "time" command will INCLUDE theses times into the
   reported runtime (it can't distinguish between operations done by
   your code and by the profiling-code)

 - I would expect the profiling code to EXCLUDE theses times - because
   they only pollute the profiling data: When I try to optimize the code
   based on the profiling-data, I'm not interested in the question how
   much time was used for the profiling-code, but I'm only interested in
   the time used in MY code.

So: 
 - "time" will give the total runtime (your code + profiling-code)
 - the gprof-output will (probably) give the runtime of your code,
   without the profiling code
and that means, that gprof should underestimate the runtime.

Well, that's what I believe, I never checked it carefully.

In addition, you have another place where gprof underestimates the
runtime (as already mentioned): 
 - when you link a library which was compiled without -pg, its runtime
   will be neglected by gprof, but not by "time". Are the
   standard-libraries (glibc for example) to which you link compiled
   with "-pg" ? if not, time spend in "printf" or "std::cout" or ...
   will be neglected by gprof too.
 - when you call a Kernel-function, which runs in Kernel space, it will
   be included by "time" - but not by "gprof".


HTH,

Axel


Re: rationale for eliding modifications to string constants

2010-09-14 Thread Axel Freyn
Hello Uday,
On Tue, Sep 14, 2010 at 11:50:11PM +0530, Uday P. Khedker wrote:
> [..]
> The point is: in your program is is only a pointer. When you pass s
> as a parameter to printf, the compiler assumes that only s is being
> used so the (effective) assignment
>
>*s = 'H'
>
> is deleted as dead code when optimization is enabled.
I can't believe your argumentation is correct. Wouldn't that mean:
When I have a code, where I only pass the pointer to a function like:

void f(int *);
int main(){
  int *s = (int *)malloc(100,sizeof(int));
  for(int i = 0; i < 100; ++i)
s[i] = 0;
  f(s);
  free(s);
}

The compiler would be allowed to erase the complete for-loop? And thus
the initialization of the array?

Or I did misunderstand your argumentation...

Axel


Re: Maybe bug in call function to static declaration variable?

2010-11-14 Thread Axel Freyn
Hi Gilberto,
On Sun, Nov 14, 2010 at 09:47:43AM -0500, Gilberto Cuba Ricardo wrote:
> Hi colleagues,
> 
> The follow program is an abstraction of on application where it
> produce an error in runtime and i don't know why it's success.
> 
> The program compile very good in all cases with Visual Studio 2005,
> 2008, 2010, MinGW 4.5.1 on Windows 7 and with GCC 4.3 on GNU Debian.
> Though, it produce an error in runtime when it's compiled with MinGW
> or GCC and next it's executed.
> 
> Anybody can help me to distinguish whether it's an error of my source
> code or a bug of gcc?
I believe it's a problem of your code.

If I reduce your example code to a minimal example showing the problem,
I obtain:

void type_schema();
struct sponge_object_schema
{
  sponge_object_schema(){
type_schema();
  }
};
void type_schema()
{
  static sponge_object_schema result;
};
int main()
{
  type_schema();
}

This creates the same runtime-error:
terminate called after throwing an instance of '__gnu_cxx::recursive_init_error'
  what():  std::exception

In this more simple example, one can see the problem: In order to create
the static object "result" in the function "type_schema", the function
"type_schema" is called itself (from the constructor needed for "type"):
this is not possible:
 - the code executes "type_schema", and allocates memory for the
   variable "result". 
 - then the constructor "sponge_object_schema" is called.
 - the constructor calls "type_schema"
 - and now in "type_shema", it is not possible to access/use the static
   object "result", as its constructor is NOT FINISHED YET
So you have a problem.

I have no idea, whether the compiler could/should detect this problem at
compile-time (well, in this particular example it could, but in general
it is impossible), but at least it's detected at runtime :-)


In your example code, the same thing happens:
"type_schema" calls the constructor for the static object
-- but then "type_schema" is again called from this
constructor.

I don't see a way how the compiler COULD create working code which
solves this problem -- For your code it would be necessary to USE the
static object before its constructor is finished...

HTH,

Axel 


Re: const char wd[6] = "Wednes", is that legal?

2010-11-30 Thread Axel Freyn
Hi Joakim,
On Tue, Nov 30, 2010 at 03:40:12PM +0100, Joakim Tjernlund wrote:
> gcc 4.4.5, powerpc32 does not fail
>  const char wd[6] = "Wednes";
> even though wd only has room for 6 chars. Is this intended?
Which language are you using? ;-)
In C++, it's forbidden (there has to be enough space for the implied
trailing "\0".
In C whoever, it's legal -- you obtain an array of 6 characters, without
a trailing "\0" ...

Axel


Re: Dumb idea for accelerating FOSS development

2011-01-12 Thread Axel Freyn
Hi,
On Wed, Jan 12, 2011 at 01:43:51PM +0100, Basile Starynkevitch wrote:
> On Wed, Jan 12, 2011 at 06:07:48AM -0500, Bill Cox wrote:
> > Unfortunately, while I could implement this idea in a few days, the
> > red tape would keep it in limbo so long that I'll likely die of old
> > age before it gets into Debian Stable.  Oh, well... here's the dumb
> > idea anyway...  In short, support a syntax in gcc like:
> > 
> > $ gcc myprog.c -lgit://github/~waywardgeek/sonic=0.1
> > 
> > In theory, this would cause gcc to do the following:
> > 
> > - Check and see if the requested library has already been
> > downloaded and built, and still in the cache
> > - If not, download the latest compatible signed version, verify
> > the signature, and compile it
> > - link to the library in the cache
> 
> At a first glance, I find your idea crazy but nice (but what about header
> files *.h of the requested library?). I would be delighted to have it. Maybe
> others don't think that way (in particular, those not working on Linux, and
> those not working on a compiler running with a network connection).
> 
> Very probably ccache is the better place to implement that, since it already 
> do
> some (preprocessed) source code cache. http://ccache.samba.org/
> 
> However, my personal feeling is that GCC is quite conservative on the user
> features it is accepting. So I won't bet that your idea will be positively
> accepted.
Well, it is not exactly what you are asking for, but the depot_tools
used in the chromium developement might be a solution:
http://www.chromium.org/developers/how-tos/depottools
The can keep track of different libraries checkout out from svn or git
repositories, and calling "gclient sync" connects to all repositories
belonging to the project and verifies that all files are up-to-date.
May be that would be a better starting point than using gcc?

Axel


Re: Proposal for automatic generation of c++ header files

2011-01-14 Thread Axel Freyn
On Fri, Jan 14, 2011 at 05:17:12PM +0200, Achilleas Margaritis wrote:
> On Fri, Jan 14, 2011 at 4:58 PM, Jonathan Wakely  
> wrote:
> > On 14 January 2011 13:26, Achilleas Margaritis wrote:
> >> My proposal does not change the language in any way, it only is a
> >> copy-and-paste job.
> >
> > That's not true, your example with an inline member function
> > demonstrates that the compiler must be changed to support your
> > proposal, so that functions defined inline are given a non-inline
> > definition that can be linked to by other translation units.
> >
> > If it was a copy'n'paste job, it could be done by an external tool,
> > which you've disputed.
> 
> My proposal doesn't change anything of the language from the
> programmer's perspective.
I think the point Jonathan wanted to make is the following: your
original example does not compile -- and can not compile without a
change of the language. If you create by hand the auto-include file you
proposed:

main.cpp:
#include "foo.hpp"
int main() {
  Foo *foo = new Foo;
  foo->bar();
  foos.push_back(foo);
}

foo.cpp:
#include 
class Foo {
  public:
void bar() {}
};
std::list foos;
static int data = 0;

foo.hpp:
#ifndef FOO_HPP
#define FOO_HPP
#include 
class Foo {
  public:
void bar();
};
extern std::list foos;
#endif //FOO_HPP

There is a violation of the C++-standard:
 - when main.cpp is compiled, the compiler reads "foo.hpp" -- and it
   learns that the class "Foo" has a member-function "bar" which can be
   call from within main.cpp -- so main.cpp is compiled without problem.
 - when "foo.cpp" is compiled, the compiler does not read "foo.hpp" and
   thus it sees that the function "bar" is defined INLINE. So the
   compiler will NOT export Foo::bar() -- it will be impossible to
   link to Foo::bar() from another compilation unit.
 - finally, you try to link both compilation units. Result: main() tries
   to call a function "Foo::bar()" -- but that does not exist ==>
   compilation error.
On my machine, I get exactly that:
g++ main.cpp foo.cpp
/tmp/ccszFpug.o: In function `main':
main.cpp:(.text+0x27): undefined reference to `Foo::bar()'
collect2: ld returned 1 exit status

So in fact you have to change the language, I believe (at least it is
necessary to remove the rule "if a member function is defined inline in
a class, it is marked as "inline" and NOT exported"). But may be there
are also other problems?

HTH,

Axel


Re: Proposal for automatic generation of c++ header files

2011-01-14 Thread Axel Freyn
On Fri, Jan 14, 2011 at 05:39:58PM +0200, Achilleas Margaritis wrote:
> > [...]
> > There is a violation of the C++-standard:
> >  - when main.cpp is compiled, the compiler reads "foo.hpp" -- and it
> >   learns that the class "Foo" has a member-function "bar" which can be
> >   call from within main.cpp -- so main.cpp is compiled without problem.
> >  - when "foo.cpp" is compiled, the compiler does not read "foo.hpp" and
> >   thus it sees that the function "bar" is defined INLINE. So the
> >   compiler will NOT export Foo::bar() -- it will be impossible to
> >   link to Foo::bar() from another compilation unit.
> >  - finally, you try to link both compilation units. Result: main() tries
> >   to call a function "Foo::bar()" -- but that does not exist ==>
> >   compilation error.
> > On my machine, I get exactly that:
> > g++ main.cpp foo.cpp
> > /tmp/ccszFpug.o: In function `main':
> > main.cpp:(.text+0x27): undefined reference to `Foo::bar()'
> > collect2: ld returned 1 exit status
> [...]
> There is a solution to that: the compiler, knowing that foo::bar is
> not an inline function, it does not inline the function but it
> automatically compiles the relevant symbol in the foo.o object file.
I agree, one can solve it -- but with a change of the language. And for
example I use the fact that member-functions which are defined inline
ARE inline (e.g. to speedup trivial access functions). 
> 
> The trick is to let the compiler know that foo::bar is not an inline
> function. The information that foo::bar is not an inline function is
> contained in the header, as I've shown:
> 
> foo.hpp:
> #ifndef FOO_HPP
> #define FOO_HPP
> #include 
> class Foo {
>  public:
>void bar();
> };
> extern std::list foos;
> #endif //FOO_HPP
> 
> So, if the compiler was informed about foo::bar not being inlined, it
> could then produce the appropriate symbol. This could happen if the
> autogenerated header is automatically included when the implementation
> file that produced the autogenerated header is compiled.
But that is not possible, as in this case you violate the C++-Standard:
Adding '#include "foo.hpp"' to foo.cpp in the example results in the
fact that class Foo is two times defined, which is illegal C++ -- and
in addition, the two definitions differ (once "bar" is inline, once it
isn't).
So the compiler would need to realize in addition that "foo.hpp" is an
autogenerated file -- and thus the compiler would have to use different
compilation rules.
> 
> The compiler could check if there is an autogenerated header in the
> same folder as the implementation file; if there is, then it is
> included automatically in the implementation file.
> 
> Then the compiler manages the clash of symbols as needed.
But with that everything becomes much more complex:
 -  When the compiler compiles "foo.cpp" -- how does he already know
that there is a "pragma autoinclude" in another file (here:
main.cpp)? Either you have to guarantee that "main.cpp" is compiled
before "foo.cpp" -- or you have to include the information "foo.hpp
will be autogenerated" also in the file "foo.cpp"
 - How can the compiler detect that the file "foo.hpp" is autgenerated
   -- and thus a different language-standard has to be used to treat
   the class "Foo"? (allowing redefinition of the class; ignoring the
   fact that the two class-definition differ, ...) -- just try adding
   '#include "foo.hpp"' in the file foo.cpp, this results in:
 g++ foo.cpp
foo.cpp:4: error: redefinition of ‘class Foo’
foo.hpp:6: error: previous definition of ‘class Foo’
 - the code is no longer understandable by other compilers: it is
   impossible to write by hand a "replacement header" with which an
   unpatched compiler (without this new extension) could compile the
   code (at least I don't see a possible way)

So I think, this extension would make it necessary at least:
 - to change the language standard (and add special rules how classes
   defined in an autogenerated-header are treated)
 - to add also in "foo.cpp" the information that "foo.hpp" will be
   autogenerated
 - to mark "foo.hpp" as being autogenerated
And it will be impossible to compile such a code with another compiler
(which does NOT know those special rules), even if one supplies by hand
the generated header files.

Axel


Re: Program editor programming c++

2008-05-29 Thread Axel Freyn
Hi,
On Thu, May 29, 2008 at 03:08:34AM -0700, Lopezio wrote:
> #include "iostream"
> int main(){
> printf("olare");
> return 0;
> }
> I get error when compile it with gcc ola.cpp -o ola.exe but it works in
> rhide environment. 
Well, your example is neither valid C-code, nor valid C++-code:
 - iostream belongs to C++, and not c
 - printf is declared in stdio.h, for C
 - you should use #include  instead of "iostream". With "", gcc
   searches only in the current directory (and in all directories given given as
   include directories on command line)
 - the filename should end on ".c" instead of ".cpp". ".cpp" is understood as
   C++-code by gcc
 - If you see nothing in the output: add a newlin "\n" to the printf-command
 - If you compile using "gcc", the compiler does not link to the C++-libraries.
   use "g++" instead.
   
If you use (C-version, ola.c)
#include 
int main(){
 printf("olare\n");
 return 0;
}
it should work with  gcc ola.c -o ola.exe. This also works with 
g++ ola.c -o ola.exe
or as
gc ola.cpp -o ola.exe
if you want

As C++ version, I would propose (in ola.cpp):
#include 
int main(){
  std::cout << "olare" << std::endl;
}
with
g++ ola.cpp -o ola.exe


The "best" programming environment depends on what you like - I'm using vim

HTH,

Axel