Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #96375 > unrolled thread

Compilation model

Started byThiago Adams <thiago.adams@gmail.com>
First post2016-11-11 03:00 -0800
Last post2016-11-12 17:10 -0800
Articles 6 — 3 participants

Back to article view | Back to comp.lang.c


Contents

  Compilation model Thiago Adams <thiago.adams@gmail.com> - 2016-11-11 03:00 -0800
    Re: Compilation model BartC <bc@freeuk.com> - 2016-11-11 11:55 +0000
      Re: Compilation model Thiago Adams <thiago.adams@gmail.com> - 2016-11-11 04:08 -0800
    Re: Compilation model "Pascal J. Bourguignon" <pjb@informatimago.com> - 2016-11-12 12:52 +0100
      Re: Compilation model Thiago Adams <thiago.adams@gmail.com> - 2016-11-12 13:47 -0800
        Re: Compilation model Thiago Adams <thiago.adams@gmail.com> - 2016-11-12 17:10 -0800

#96375 — Compilation model

FromThiago Adams <thiago.adams@gmail.com>
Date2016-11-11 03:00 -0800
SubjectCompilation model
Message-ID<c7dca28a-32cc-49ec-a4c1-bf7dea851cb7@googlegroups.com>
I am start to think a compilation model that consider a group of .c files is good, and I want to know what do you think.


For instance. Let's say I have a group of files that correspond to one functionality, send e-mail.

file1.h, file1.c ...  fileN.h, fileN.c

and the one published header. mail.h

I think that makes sense to think about a big block (mail.c)

file : mail.c
---

#include "file1.c"
..
#include "fileN.c"

---

I know that this model doesn't correspond to the unit model, because the parsed declarations and macros and statics from the previous files will be
available.

Advantages -  easy global analysis
Having a concept of group or program, is possible to see if any part of it is used. (enum, function, declaration etc)
The parsed declarations will not be parsed again and again for each unit.

For libraries, you can not say "this function is not used" because it may be used later. But, for libraries could be a easy way to publish.

I know some libraries are distributed in one file.

Is there a tool for this? (merge)

The job of the tool I think is to fix the static void f() problem creating reserved names and removing macros.

Something created could be:

#pragma source "file1.c"
#pragma source "file2.c"


This pragma could do the job of renaming statics, and clearing macros created inside file1.c etc.



----------

Global analysis using current unit model.
I think each compilation unit  will generate the AST. 
So if you have 100 files, that means 100 ASTs that need to be checked for the parts in common. Let's say I have and enum E {A, B, C}

Some of the 100 ASTs can have the E enum being the same entity, each A B C has to be identified as being the same thing. Doing this, the global checker can say "hey look, you have created an C enum value but you never use it in your program".



---





[toc] | [next] | [standalone]


#96376

FromBartC <bc@freeuk.com>
Date2016-11-11 11:55 +0000
Message-ID<o04bie$gb4$1@dont-email.me>
In reply to#96375
On 11/11/2016 11:00, Thiago Adams wrote:
>
> I am start to think a compilation model that consider a group of .c files is good, and I want to know what do you think.

> ----------
>
> Global analysis using current unit model.
> I think each compilation unit  will generate the AST.
> So if you have 100 files, that means 100 ASTs that need to be checked for the parts in common. Let's say I have and enum E {A, B, C}
>
> Some of the 100 ASTs can have the E enum being the same entity, each A B C has to be identified as being the same thing. Doing this, the global checker can say "hey look, you have created an C enum value but you never use it in your program".
> ---

The last compiler I did (not for C) only compiles whole projects, as 
will the next one (**).

That does have a number of advantages such as those you mentioned. (Also 
global optimisations or inlining if I ever get around to doing that.)

However the language being compiled is more strictly modular than C is.

With C, the enum is not really the same one across all modules; each 
module just contains an identical definition. (This applies to all 
'passive' entities such as enums, typedefs and macros. Only variables 
and functions are really shared.)

The problem with C source files, and include files especially, is that 
they contain macros, conditional code and so on that are sensitive to 
external factors.

Suppose one of the include files makes use of something like __path__ or 
__line__ or __time__. Then that could make the following source code be 
compiled a little differently.

Or entire blocks of source could be conditional depending on some set, 
or not set, by a compiler option, so that your analyser doesn't see 
them. Then it becomes harder to do an unequivocal analysis of the source 
as it might depend on environmental factors.

--------------------------
(** Actually you compile only one module, and it will then locate and 
compile all dependencies based on the 'import' statements seen. If this 
is the main module, it will compile the whole program.)

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#96377

FromThiago Adams <thiago.adams@gmail.com>
Date2016-11-11 04:08 -0800
Message-ID<116523f7-3197-40f8-bc32-5e9fcef6113b@googlegroups.com>
In reply to#96376
On Friday, November 11, 2016 at 9:55:32 AM UTC-2, Bart wrote:
> On 11/11/2016 11:00, Thiago Adams wrote:
> >
> > I am start to think a compilation model that consider a group of .c files is good, and I want to know what do you think.
> 
> > ----------
> >
> > Global analysis using current unit model.
> > I think each compilation unit  will generate the AST.
> > So if you have 100 files, that means 100 ASTs that need to be checked for the parts in common. Let's say I have and enum E {A, B, C}
> >
> > Some of the 100 ASTs can have the E enum being the same entity, each A B C has to be identified as being the same thing. Doing this, the global checker can say "hey look, you have created an C enum value but you never use it in your program".
> > ---
> 
> The last compiler I did (not for C) only compiles whole projects, as 
> will the next one (**).
> 
> That does have a number of advantages such as those you mentioned. (Also 
> global optimisations or inlining if I ever get around to doing that.)
> 
> However the language being compiled is more strictly modular than C is.
> 
> With C, the enum is not really the same one across all modules; each 
> module just contains an identical definition. (This applies to all 
> 'passive' entities such as enums, typedefs and macros. Only variables 
> and functions are really shared.)
> 
> The problem with C source files, and include files especially, is that 
> they contain macros, conditional code and so on that are sensitive to 
> external factors.

Yes, I agree.
But also there is a pre-compilers headers solution, that I think is something to say "this block is always like this"

In VC++, when you use pre-compiler headers, the first include must be #include "stdafx.h". I think this is the solution to ensure that the block is the same (nothing included before to change it's macros)

So, maybe something like that in compilers could work.
I think in the past, the problem was memory
and small parts are just the way to go.

Nowadays, you can have millions of lines, but they are not related closer with each other. So the concept of "compilation unit group" could join related c files.



[toc] | [prev] | [next] | [standalone]


#96411

From"Pascal J. Bourguignon" <pjb@informatimago.com>
Date2016-11-12 12:52 +0100
Message-ID<m28tsoncej.fsf@larissa.home>
In reply to#96375
Thiago Adams <thiago.adams@gmail.com> writes:

> I am start to think a compilation model that consider a group of .c files is good, and I want to know what do you think.
>
>
> For instance. Let's say I have a group of files that correspond to one functionality, send e-mail.
>
> file1.h, file1.c ...  fileN.h, fileN.c
>
> and the one published header. mail.h
>
> I think that makes sense to think about a big block (mail.c)
> […]
> Something created could be:
>
> #pragma source "file1.c"
> #pragma source "file2.c"

-----( main.c )---------------------------------------------------------
#include "file1.h"
#include "file2.h"
…
#include "fileN.h"

// No separate compilation:
#include "file1.c"
#include "file2.c"
…
#include "fileN.c"
------------------------------------------------------------------------


-----( Makefile )-------------------------------------------------------
all: main
main:main.c file1.h file1.c file2.h file2.c … fileN.h fileN.c
   $(CC) -o main -I. main.c
------------------------------------------------------------------------

--
__Pascal Bourguignon__

[toc] | [prev] | [next] | [standalone]


#96431

FromThiago Adams <thiago.adams@gmail.com>
Date2016-11-12 13:47 -0800
Message-ID<516e8dac-3669-4da0-8634-26062cce5734@googlegroups.com>
In reply to#96411
On Saturday, November 12, 2016 at 9:52:28 AM UTC-2, Pascal J. Bourguignon wrote:
> Thiago Adams  writes:
> 
> > I am start to think a compilation model that consider a group of .c files is good, and I want to know what do you think.
> >
> >
> > For instance. Let's say I have a group of files that correspond to one functionality, send e-mail.
> >
> > file1.h, file1.c ...  fileN.h, fileN.c
> >
> > and the one published header. mail.h
> >
> > I think that makes sense to think about a big block (mail.c)
> > […]
> > Something created could be:
> >
> > #pragma source "file1.c"
> > #pragma source "file2.c"
> 
> -----( main.c )---------------------------------------------------------
> #include "file1.h"
> #include "file2.h"
> …
> #include "fileN.h"
> 
> // No separate compilation:
> #include "file1.c"
> #include "file2.c"
> …
> #include "fileN.c"
> ------------------------------------------------------------------------
> 
> 
> -----( Makefile )-------------------------------------------------------
> all: main
> main:main.c file1.h file1.c file2.h file2.c … fileN.h fileN.c
>    $(CC) -o main -I. main.c
> ------------------------------------------------------------------------
> 
> --
> __Pascal Bourguignon__

I  have create a file like this to analyze my static analyzer globally using itself without have to implement that "AST merge" algorithm. I added only c files not h.
 

Nowadays, there are some refactoring tools to rename variables, or struct members for instance. This is another situation where the rename process need to understand in different units that the name are the same entity.

Sometimes, for runtime type identification, we need one ID for each type. To avoid repetitions or manual control I was wondering some alternative.

I know some compiler have __COUNT__ macro. But i think its by translation unit. ?

struct X
{
   size_t* type;
};

I was thinking in to use the "linker" job.


#include <stdio.h>

typedef struct
{
   size_t type;    
}X;


void X_Init(X* p)
{
    p->type = (size_t) &X_Init;
}

int main()
{
    X x;
    X_Init(&x);
    return 0;
}

The link is something that does the "merge" and have unique ids.






[toc] | [prev] | [next] | [standalone]


#96446

FromThiago Adams <thiago.adams@gmail.com>
Date2016-11-12 17:10 -0800
Message-ID<3f708a4d-fcac-4540-bfb3-0f6d5017038f@googlegroups.com>
In reply to#96431
On Saturday, November 12, 2016 at 7:48:01 PM UTC-2, Thiago Adams wrote:

> Sometimes, for runtime type identification, we need one ID for each type. To avoid repetitions or manual control I was wondering some alternative.
> 
> I know some compiler have __COUNT__ macro. But i think its by translation unit. ?
> 
> struct X
> {
>    size_t* type;
> };
> 
> I was thinking in to use the "linker" job.
> 
> 
> #include <stdio.h>
> 
> typedef struct
> {
>    size_t type;    
> }X;
> 
> 
> void X_Init(X* p)
> {
>     p->type = (size_t) &X_Init;
> }
> 
> int main()
> {
>     X x;
>     X_Init(&x);
>     return 0;
> }
> 
> The link is something that does the "merge" and have unique ids.


The problem with the previous alternative, is that I cannot use with switch
because case (size_t) &X_Init is not an constant expression.

    switch (x.type)
    { 
    case (size_t) &X_Init:
      break;
    }

I guess ifs would not be so efficient as switch, and then manual solution of define the ids is better than automatic.


The problem of __COUNTER__ (I haven't tried, but I guess) is that only works for one  translation unit.

So, the subject is related with compilation model, because with a group of translation units we can generate unique ids for each type.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web