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


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

The language between C and C++ I would like to have

Started byThiago Adams <thiago.adams@gmail.com>
First post2020-03-11 07:43 -0700
Last post2020-03-23 04:57 -0700
Articles 18 — 9 participants

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


Contents

  The language between C and C++ I would like to have Thiago Adams <thiago.adams@gmail.com> - 2020-03-11 07:43 -0700
    Re: The language between C and C++ I would like to have chad <cdalten@gmail.com> - 2020-03-11 09:20 -0700
      Re: The language between C and C++ I would like to have Thiago Adams <thiago.adams@gmail.com> - 2020-03-11 09:34 -0700
    Re: The language between C and C++ I would like to have Bart <bc@freeuk.com> - 2020-03-11 16:33 +0000
      Re: The language between C and C++ I would like to have Thiago Adams <thiago.adams@gmail.com> - 2020-03-11 13:02 -0700
    Re: The language between C and C++ I would like to have Ian Collins <ian-news@hotmail.com> - 2020-03-12 08:20 +1300
      Re: The language between C and C++ I would like to have Thiago Adams <thiago.adams@gmail.com> - 2020-03-11 12:45 -0700
        Re: The language between C and C++ I would like to have Ian Collins <ian-news@hotmail.com> - 2020-03-12 09:02 +1300
          Re: The language between C and C++ I would like to have Thiago Adams <thiago.adams@gmail.com> - 2020-03-11 13:07 -0700
            Re: The language between C and C++ I would like to have scott@slp53.sl.home (Scott Lurndal) - 2020-03-11 21:13 +0000
              Re: The language between C and C++ I would like to have already5chosen@yahoo.com - 2020-03-11 14:47 -0700
                Re: The language between C and C++ I would like to have David Brown <david.brown@hesbynett.no> - 2020-03-11 22:55 +0100
                Re: The language between C and C++ I would like to have Thiago Adams <thiago.adams@gmail.com> - 2020-03-12 05:23 -0700
            Re: The language between C and C++ I would like to have Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-03-11 22:29 +0000
    Re: The language between C and C++ I would like to have Thiago Adams <thiago.adams@gmail.com> - 2020-03-12 05:40 -0700
      Re: The language between C and C++ I would like to have chad <cdalten@gmail.com> - 2020-03-12 13:06 -0700
    Re: The language between C and C++ I would like to have Philipp Klaus Krause <pkk@spth.de> - 2020-03-22 10:35 +0100
      Re: The language between C and C++ I would like to have Thiago Adams <thiago.adams@gmail.com> - 2020-03-23 04:57 -0700

#150476 — The language between C and C++ I would like to have

FromThiago Adams <thiago.adams@gmail.com>
Date2020-03-11 07:43 -0700
SubjectThe language between C and C++ I would like to have
Message-ID<5a0784c9-ea64-409e-afd8-4aa4eb0cfd01@googlegroups.com>
All these features are my suggestion for the C language.



# Member initializer

struct X
{
   int i = 1;
   struct Point pt = { .x = 1, .y = 1 };
};

# Empty Initializer / Compound literal

int main()
{
   struct X x = {}; 
   
   //same as C99
   struct x = { . i = 1, .pt = {.x = 1, .y = 1 } };
   
   x = (struct X){}; 
   
   //same as C99
   x = (struct X){ . i = 1, .pt = {.x = 1, .y = 1 } };
}


int main()
{
  struct X x; //same as C today (uninitialized)
  
  int i = {};  //same as i = 0;
  int* p = {};  //same as p = 0;
  float f = {}; //same as f = 0.0f
  //etc..
}

# Operator destroy

Does nothing for ints, structs etc.. 
Can be override to do something.

struct Person
{
    char * name = NULL;
};

//overriding destroy

void operator destroy(struct X* p)
{
  free(p->name);
  
  //calling the default destroy   (does nothing in this case)
  default destroy(p); 
}

int main()
{
   struct X x;
   //...
   destroy(x);
}

# Calling destroy at the end of scope

Destroy is not called automatically at the end of scope unless 
you put 'auto'.

struct Person
{
    char * name = NULL;
};

int main()
{
   auto struct X x; 
   
} //destroy(x) is called at the end of scope

# Operator new

struct X
{
    char * name = NULL;
};

int main()
{
  struct X* pX = new (struct X){ }; 
  
  //Same as:
  
  struct X* pX = malloc(sizeof  * pX);
  if (pX) 
  {
    *pX = (struct X){};
  }  
}

# Overriding new

struct X
{
    char * name = NULL;
};

struct X* operator new(struct X* def)
{
  struct X* p = malloc(sizeof * p);
  if (p)
  {
    *p = *def;
  }
  return p;
}

int main()
{
  struct X* pX = new (struct X) {};
}

# Auto pointers

struct X
{
    char * name = NULL;
};

int main()
{
  struct X* auto pX = new (struct X) {};
  
  destroy(pX);
  
  //Same of
  
  if (pX)
  {
    destroy(*pX); 
    free(pX);
  }  
}

# Overring destroy for auto pointers

struct X
{
    char * name = NULL;
};

void operator destroy(struct X* auto p)
{   
   //...your code here
   
   default destroy(p);
}

The default destroy for auto pointer is the same of

if (pX)
{
  destroy(*pX);
  free(pX);
}

# Automatically calling destroy for auto pointers

Use the auto modifier in your pointer.

struct X
{
    char * name = NULL;
};

int main()
{
  struct X* auto pX = new (struct X) {};
   
} //destroy(pX) is called at the end of scope

# Auto in struct members

auto in struct members will generate the default destructor 
calling destroy for each member (recursively)

struct Y
{
  int i;
};

struct X
{ 
  auto struct Y y;
  struct Y * auto pY;
};

int main()
{
  auto struct X x = {};  
} 

calls destroy(x)..
that will call destroy(x.y) and destroy(x.pY) that will 
call destroy(*pX) and free(pX)

# if with initializer
Same of C++. See the use of auto.

struct Y
{
  int i;
};

struct X
{ 
  auto struct Y y;
  struct Y * auto pY;
};

int main()
{
  if (struct X* auto pX = new (struct X){}, p)
  {
  }//calls destroy(pX);
} 

# Overriding destroy for existing types

void operator destroy (FILE * auto f)
{
  fclose(f);
}

int main()
{
  if (FILE* auto f = fopen("file.txt", "r"), f)
  {
  }//calls custom destroy(f) that calls fclose;
} 

# Operator move

 struct X * auto pX1 = new (struct X){};
 struct X * auto pX2 = {};
 
 pX2 = move(pX1);

 //Same as:
 pX2 = pX1;
 pX1 = NULL;

# Lambdas
Similar of C++.

Lambdas without capture will be function pointers. 
Lambdas with capture (to be defined)

# Custom operators

We can create other operators they are like functions that can be overrided. 
But they have internal linkage only.

struct Box
{
    int id = 1;
};

void operator draw(struct Box* pBox)
{
    printf("Box");
}

struct Circle
{
    int id = 2;
};

void operator draw(struct Circle* pCircle)
{
    printf("Circle");
}

int main()
{
  struct Box box = {};
  struct Circle circle = {};
  
  draw(&box);
  draw(&cicle);
}

# Polimorphism

Pointers that can point to a set of types.
Types must have a common discriminant.

Sample:

 
//forward declaration
struct <struct Box | struct Circle> Shape;  
 
//pShape points to box or circle
struct Shape* pShape;
 
struct Box
{
    int id = 1; //discriminant
};

void operator draw(struct Box* pBox)
{
    printf("Box");
}

struct Circle
{
    int id = 2; //discriminant
};

void operator draw(struct Circle* pCircle)
{
    printf("Circle");
}

int main()
{
  struct <Box | Circle>* auto shapes[2] = {};
  
  shapes[0] = new (struct Box){};
  shapes[1] = new (struct Circle){};
  
  for (int i = 0; i < 2; i++)
  {    
    //runtime selection according with the discriminant
    //draw must be an operator in box and circle otherwise compile time error
    draw(shapes[i]); 
    
    //id is the only data member of Shape
    printf("%d", shapes[i].id); //valid
  }
  
}

## Parametrized types/operators
TODO

(
 These features are not in sync with my current transpiler
 http://thradams.com/web/cprime.html
 but they are my current view and something I would like
 to have/implement.
)

What do you think?



[toc] | [next] | [standalone]


#150479

Fromchad <cdalten@gmail.com>
Date2020-03-11 09:20 -0700
Message-ID<42da331b-9419-4333-b43b-54550e3c712a@googlegroups.com>
In reply to#150476
On Wednesday, March 11, 2020 at 7:43:33 AM UTC-7, Thiago Adams wrote:
> All these features are my suggestion for the C language.
> 
> 
> 
> # Member initializer
> 
> struct X
> {
>    int i = 1;
>    struct Point pt = { .x = 1, .y = 1 };
> };
> 
> # Empty Initializer / Compound literal
> 
> int main()
> {
>    struct X x = {}; 
>    
>    //same as C99
>    struct x = { . i = 1, .pt = {.x = 1, .y = 1 } };
>    
>    x = (struct X){}; 
>    
>    //same as C99
>    x = (struct X){ . i = 1, .pt = {.x = 1, .y = 1 } };
> }
> 
> 
> int main()
> {

Awesome. There with this construct, there is no way I can do runtime polymorphism!

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


#150481

FromThiago Adams <thiago.adams@gmail.com>
Date2020-03-11 09:34 -0700
Message-ID<08ff06ef-ac06-4139-830a-356aea6761d4@googlegroups.com>
In reply to#150479
On Wednesday, March 11, 2020 at 1:20:28 PM UTC-3, chad wrote:
> On Wednesday, March 11, 2020 at 7:43:33 AM UTC-7, Thiago Adams wrote:
> > All these features are my suggestion for the C language.
> > 
> > 
> > 
> > # Member initializer
> > 
> > struct X
> > {
> >    int i = 1;
> >    struct Point pt = { .x = 1, .y = 1 };
> > };
> > 
> > # Empty Initializer / Compound literal
> > 
> > int main()
> > {
> >    struct X x = {}; 
> >    
> >    //same as C99
> >    struct x = { . i = 1, .pt = {.x = 1, .y = 1 } };
> >    
> >    x = (struct X){}; 
> >    
> >    //same as C99
> >    x = (struct X){ . i = 1, .pt = {.x = 1, .y = 1 } };
> > }
> > 
> > 
> > int main()
> > {
> 
> Awesome. There with this construct, there is no way I can do runtime polymorphism!

Sorry, I didn't understand you comment.
Where is the connection with polymorphism?

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


#150480

FromBart <bc@freeuk.com>
Date2020-03-11 16:33 +0000
Message-ID<9p8aG.709959$7i5.348395@fx35.am4>
In reply to#150476
On 11/03/2020 14:43, Thiago Adams wrote:
> All these features are my suggestion for the C language.
> 
> 
> 
> # Member initializer
> 
> struct X
> {
>     int i = 1;
>     struct Point pt = { .x = 1, .y = 1 };
> };
> 

I think I've made some objections before. But, if have a destructor, 
then why not have a constructor where you can put this initialisation stuff?

(I can see one problem with that, as a constructor is a runtime 
operation, and you may want this initialisation with static objects.)

Also, suppose you create a duplicate struct Y but with pt initialised to 
(2,2) instead of (1,1), and then form a union of X and Y structs? (This 
would be helped I think with my constructor idea.)

> # Overriding new
> 
> struct X
> {
>      char * name = NULL;
> };
> 
> struct X* operator new(struct X* def)

Maybe 'new' can be the constructor I mentioned except that new() here is 
called explicitly rather than implicitly.

> # Polimorphism
> 
> Pointers that can point to a set of types.
> Types must have a common discriminant.
> 
> Sample:
> 
>   
> //forward declaration
> struct <struct Box | struct Circle> Shape;
>   
> //pShape points to box or circle
> struct Shape* pShape;
>   
> struct Box
> {
>      int id = 1; //discriminant
> };


Perhaps you want a Tagged Union here (a 'sum type') where the 
discriminant is an implicit field that is run-time checked.

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


#150490

FromThiago Adams <thiago.adams@gmail.com>
Date2020-03-11 13:02 -0700
Message-ID<a76b8df7-2ce0-499a-ac3d-e6cf65e29668@googlegroups.com>
In reply to#150480
On Wednesday, March 11, 2020 at 1:33:19 PM UTC-3, Bart wrote:
> On 11/03/2020 14:43, Thiago Adams wrote:
> > All these features are my suggestion for the C language.
> > 
> > 
> > 
> > # Member initializer
> > 
> > struct X
> > {
> >     int i = 1;
> >     struct Point pt = { .x = 1, .y = 1 };
> > };
> > 
> 
> I think I've made some objections before. But, if have a destructor, 
> then why not have a constructor where you can put this initialisation stuff?
> 
> (I can see one problem with that, as a constructor is a runtime 
> operation, and you may want this initialisation with static objects.)
> 
> Also, suppose you create a duplicate struct Y but with pt initialised to 
> (2,2) instead of (1,1), and then form a union of X and Y structs? (This 
> would be helped I think with my constructor idea.)
> 
> > # Overriding new
> > 
> > struct X
> > {
> >      char * name = NULL;
> > };
> > 
> > struct X* operator new(struct X* def)
> 
> Maybe 'new' can be the constructor I mentioned except that new() here is 
> called explicitly rather than implicitly.

Initially I was using init. It still an option. 
init brings a lot of more details. 

The default init for C could use return codes for runtime errors
to avoid exceptions. The final design using 'constructor/init' would be
very similar of C++ removing exceptions. Then new operator would have 
to call init as well and more...just like C++.
I don't have complains about this part of C++. But I am avoiding
fancy initialization in my code (in C++ and C).
In practice that means that my constructors just put the object at
an empty state that can be destroyed. The initialization that can 
fail is done is another function.

for instance, conceptually, instead of:

File f("file.txt")

I prefer:

file f = {};
open(f, "file.txt");

so at this moment init would not simplify my C code because the part that
may fail I put in another function like start/open/init .

The empty initialization would remove 1 macro per type in my code.
The new operator for compound literal would remove 1 function per
type that is allocated on the heap.
and destroy would remove many lines from implementation 
and one line (call) for each auto variable.

> > # Polimorphism
> > 
> > Pointers that can point to a set of types.
> > Types must have a common discriminant.
> > 
> > Sample:
> > 
> >   
> > //forward declaration
> > struct <struct Box | struct Circle> Shape;
> >   
> > //pShape points to box or circle
> > struct Shape* pShape;
> >   
> > struct Box
> > {
> >      int id = 1; //discriminant
> > };
> 
> 
> Perhaps you want a Tagged Union here (a 'sum type') where the 
> discriminant is an implicit field that is run-time checked.

With tagged unions the tag is not intrusive and if the size of objects
are very different the allocation is not intelligent.
Having two containers pointing to the same object (lest say a tree and map)
would put one tag per instance of each item in each container.

The intrusive model (where the tag is part of the object) we have just
pointers in each container and the objects can have different sizes.

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


#150486

FromIan Collins <ian-news@hotmail.com>
Date2020-03-12 08:20 +1300
Message-ID<hcss0jFnq38U2@mid.individual.net>
In reply to#150476
On 12/03/2020 03:43, Thiago Adams wrote:
> All these features are my suggestion for the C language.

Why don't you just use a subset of C++ that meets your requirements?

-- 
Ian.

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


#150487

FromThiago Adams <thiago.adams@gmail.com>
Date2020-03-11 12:45 -0700
Message-ID<e63e05bb-f783-4c07-83b2-3c85a0448304@googlegroups.com>
In reply to#150486
On Wednesday, March 11, 2020 at 4:21:00 PM UTC-3, Ian Collins wrote:
> On 12/03/2020 03:43, Thiago Adams wrote:
> > All these features are my suggestion for the C language.
> 
> Why don't you just use a subset of C++ that meets your requirements?
> 

I think it is an interesting exercise, but the result is not 
the same. The other option is to use C.

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


#150489

FromIan Collins <ian-news@hotmail.com>
Date2020-03-12 09:02 +1300
Message-ID<hcsudtFnq38U3@mid.individual.net>
In reply to#150487
On 12/03/2020 08:45, Thiago Adams wrote:
> On Wednesday, March 11, 2020 at 4:21:00 PM UTC-3, Ian Collins wrote:
>> On 12/03/2020 03:43, Thiago Adams wrote:
>>> All these features are my suggestion for the C language.
>>
>> Why don't you just use a subset of C++ that meets your requirements?
>>
> 
> I think it is an interesting exercise, but the result is not
> the same. The other option is to use C.

Not the same as what?

-- 
Ian.

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


#150491

FromThiago Adams <thiago.adams@gmail.com>
Date2020-03-11 13:07 -0700
Message-ID<73dbf034-a127-4a55-87db-9ec78bddf33d@googlegroups.com>
In reply to#150489
On Wednesday, March 11, 2020 at 5:02:16 PM UTC-3, Ian Collins wrote:
> On 12/03/2020 08:45, Thiago Adams wrote:
> > On Wednesday, March 11, 2020 at 4:21:00 PM UTC-3, Ian Collins wrote:
> >> On 12/03/2020 03:43, Thiago Adams wrote:
> >>> All these features are my suggestion for the C language.
> >>
> >> Why don't you just use a subset of C++ that meets your requirements?
> >>
> > 
> > I think it is an interesting exercise, but the result is not
> > the same. The other option is to use C.
> 
> Not the same as what?

The result is different from my suggestion.

For instance, in my suggestion I can have:

void operator destroy (FILE * auto f)
{
  fclose(f);
}

int main()
{
  if (FILE* auto f = fopen("file.txt", "r"), f)
  {
  }
}
In C++ we need a wrapper for FILE. Or smart pointer that is a 
parametrized wrapper.
For the polymorphic part is also very difficult to do (libs+templates)
in C++. But alternative solution exists.


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


#150492

Fromscott@slp53.sl.home (Scott Lurndal)
Date2020-03-11 21:13 +0000
Message-ID<6wcaG.117996$Pj7.105399@fx14.iad>
In reply to#150491
Thiago Adams <thiago.adams@gmail.com> writes:
>On Wednesday, March 11, 2020 at 5:02:16 PM UTC-3, Ian Collins wrote:
>> On 12/03/2020 08:45, Thiago Adams wrote:
>> > On Wednesday, March 11, 2020 at 4:21:00 PM UTC-3, Ian Collins wrote:
>> >> On 12/03/2020 03:43, Thiago Adams wrote:
>> >>> All these features are my suggestion for the C language.
>> >>
>> >> Why don't you just use a subset of C++ that meets your requirements?
>> >>
>> > 
>> > I think it is an interesting exercise, but the result is not
>> > the same. The other option is to use C.
>> 
>> Not the same as what?
>
>The result is different from my suggestion.
>
>For instance, in my suggestion I can have:
>
>void operator destroy (FILE * auto f)
>{
>  fclose(f);
>}
>
>int main()
>{
>  if (FILE* auto f = fopen("file.txt", "r"), f)
>  {
>  }
>}
>In C++ we need a wrapper for FILE. Or smart pointer that is a 
>parametrized wrapper.

 In C++, the FILE object is private to the class.   The class
provides members to access and store data in the file, which in turn,
use the stdio facilities.   This makes it easy to change the underlying
access paradigm (i.e. use posix open/pread/pwrite/close or mmap) without
having to modify any clients of the class.

 The constructor opens the file, and the destructor closes it.

 I see no benefit in exposing FILE* to the client of the class, that's
just plain wrong.

something along these lines (illustrative example only):

class c_file {
   FILE *f_file;

public:
   c_file(const char *filename) { f_file = fopen(); if (f_file == NULL) throw error; }
   ~c_file(void) { if (f_file != NULL) fclose(f_file); }
   bool read_sequential_not_thread_safe(char *buffer, size_t buffersize) { return
fread(f_file, buffer, buffersize) != -1; }
   bool read_random_thread_safe(char *buffer, size_t buffersize, off_t offset) { return
pread(fileno(f_file), buffer, buffersize, offset) == buffersize; }

etc.

};

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


#150493

Fromalready5chosen@yahoo.com
Date2020-03-11 14:47 -0700
Message-ID<0c09a46b-938b-4f9f-9f1c-0c67cfe8c956@googlegroups.com>
In reply to#150492
On Wednesday, March 11, 2020 at 11:13:48 PM UTC+2, Scott Lurndal wrote:
> Thiago Adams <thiago.adams@gmail.com> writes:
> >On Wednesday, March 11, 2020 at 5:02:16 PM UTC-3, Ian Collins wrote:
> >> On 12/03/2020 08:45, Thiago Adams wrote:
> >> > On Wednesday, March 11, 2020 at 4:21:00 PM UTC-3, Ian Collins wrote:
> >> >> On 12/03/2020 03:43, Thiago Adams wrote:
> >> >>> All these features are my suggestion for the C language.
> >> >>
> >> >> Why don't you just use a subset of C++ that meets your requirements?
> >> >>
> >> > 
> >> > I think it is an interesting exercise, but the result is not
> >> > the same. The other option is to use C.
> >> 
> >> Not the same as what?
> >
> >The result is different from my suggestion.
> >
> >For instance, in my suggestion I can have:
> >
> >void operator destroy (FILE * auto f)
> >{
> >  fclose(f);
> >}
> >
> >int main()
> >{
> >  if (FILE* auto f = fopen("file.txt", "r"), f)
> >  {
> >  }
> >}
> >In C++ we need a wrapper for FILE. Or smart pointer that is a 
> >parametrized wrapper.
> 
>  In C++, the FILE object is private to the class.   The class
> provides members to access and store data in the file, which in turn,
> use the stdio facilities.   This makes it easy to change the underlying
> access paradigm (i.e. use posix open/pread/pwrite/close or mmap) without
> having to modify any clients of the class.
> 
>  The constructor opens the file, and the destructor closes it.
> 
>  I see no benefit in exposing FILE* to the client of the class, that's
> just plain wrong.
> 
> something along these lines (illustrative example only):
> 
> class c_file {
>    FILE *f_file;
> 
> public:
>    c_file(const char *filename) { f_file = fopen(); if (f_file == NULL) throw error; }
>    ~c_file(void) { if (f_file != NULL) fclose(f_file); }
>    bool read_sequential_not_thread_safe(char *buffer, size_t buffersize) { return
> fread(f_file, buffer, buffersize) != -1; }
>    bool read_random_thread_safe(char *buffer, size_t buffersize, off_t offset) { return
> pread(fileno(f_file), buffer, buffersize, offset) == buffersize; }
> 
> etc.
> 
> };

The point is not about exposing this or that internal field.
The point is that constructor can't fail. One places parts of initialization that can fail in separate method, typically called init() or open() or construct(). This method reports failures via C-style error code.
If you follow such pattern systematically, including all libraries, it totally eliminate the need for exceptions. And that, in turn, eliminates the need for RAII.
It's all documented in google's C++ style guide and other sane style guides.

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


#150496

FromDavid Brown <david.brown@hesbynett.no>
Date2020-03-11 22:55 +0100
Message-ID<r4bmpe$t1$1@dont-email.me>
In reply to#150493
On 11/03/2020 22:47, already5chosen@yahoo.com wrote:
> On Wednesday, March 11, 2020 at 11:13:48 PM UTC+2, Scott Lurndal wrote:
>> Thiago Adams <thiago.adams@gmail.com> writes:
>>> On Wednesday, March 11, 2020 at 5:02:16 PM UTC-3, Ian Collins wrote:
>>>> On 12/03/2020 08:45, Thiago Adams wrote:
>>>>> On Wednesday, March 11, 2020 at 4:21:00 PM UTC-3, Ian Collins wrote:
>>>>>> On 12/03/2020 03:43, Thiago Adams wrote:
>>>>>>> All these features are my suggestion for the C language.
>>>>>>
>>>>>> Why don't you just use a subset of C++ that meets your requirements?
>>>>>>
>>>>>
>>>>> I think it is an interesting exercise, but the result is not
>>>>> the same. The other option is to use C.
>>>>
>>>> Not the same as what?
>>>
>>> The result is different from my suggestion.
>>>
>>> For instance, in my suggestion I can have:
>>>
>>> void operator destroy (FILE * auto f)
>>> {
>>>   fclose(f);
>>> }
>>>
>>> int main()
>>> {
>>>   if (FILE* auto f = fopen("file.txt", "r"), f)
>>>   {
>>>   }
>>> }
>>> In C++ we need a wrapper for FILE. Or smart pointer that is a
>>> parametrized wrapper.
>>
>>   In C++, the FILE object is private to the class.   The class
>> provides members to access and store data in the file, which in turn,
>> use the stdio facilities.   This makes it easy to change the underlying
>> access paradigm (i.e. use posix open/pread/pwrite/close or mmap) without
>> having to modify any clients of the class.
>>
>>   The constructor opens the file, and the destructor closes it.
>>
>>   I see no benefit in exposing FILE* to the client of the class, that's
>> just plain wrong.
>>
>> something along these lines (illustrative example only):
>>
>> class c_file {
>>     FILE *f_file;
>>
>> public:
>>     c_file(const char *filename) { f_file = fopen(); if (f_file == NULL) throw error; }
>>     ~c_file(void) { if (f_file != NULL) fclose(f_file); }
>>     bool read_sequential_not_thread_safe(char *buffer, size_t buffersize) { return
>> fread(f_file, buffer, buffersize) != -1; }
>>     bool read_random_thread_safe(char *buffer, size_t buffersize, off_t offset) { return
>> pread(fileno(f_file), buffer, buffersize, offset) == buffersize; }
>>
>> etc.
>>
>> };
> 
> The point is not about exposing this or that internal field.

> The point is that constructor can't fail. One places parts of
> initialization that can fail in separate method, typically called
> init() or open() or construct(). This method reports failures via
> C-style error code.

> If you follow such pattern systematically, including all libraries,
> it totally eliminate the need for exceptions. 

That can be a good thing or a bad thing.  There are reasons to prefer 
exceptions, and reasons to prefer not having exceptions.  No one choice 
fits all circumstances ideally.

> And that, in turn,
> eliminates the need for RAII.

Nonsense.  RAII is not dependent on exceptions, nor are exceptions 
dependent on RAII - though they can often be useful together.  And RAII 
is a feature that you want available for when it makes coding easier and 
safer - it is not something you would ever want to eliminate (in the way 
that you might want to eliminate exceptions).

> It's all documented in google's C++ style guide and other sane style
> guides.
> 

Google's C++ guide, as with a number of C++ guides, recommends avoiding 
exceptions.  It does not recommend avoiding RAII.

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


#150505

FromThiago Adams <thiago.adams@gmail.com>
Date2020-03-12 05:23 -0700
Message-ID<071abd3b-ffe4-438d-b9f9-84ad2d8f662c@googlegroups.com>
In reply to#150493
On Wednesday, March 11, 2020 at 6:47:54 PM UTC-3, already...@yahoo.com wrote:
...
> The point is not about exposing this or that internal field.
> The point is that constructor can't fail. One places parts of initialization that can fail in separate method, typically called init() or open() or construct(). This method reports failures via C-style error code.

In C++ it first creates an object with default and after calls ctor.

struct X {

  int i = 1;
  X() {
    assert(i == 1);
    i = 2;
  }

};


int main() {
  X x = {};
  assert(x.i == 2);
}

In C++ this expression can throw.

X x = {};

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


#150498

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2020-03-11 22:29 +0000
Message-ID<slrnr6iphk.1r7q.grahn+nntp@frailea.sa.invalid>
In reply to#150491
On Wed, 2020-03-11, Thiago Adams wrote:
> On Wednesday, March 11, 2020 at 5:02:16 PM UTC-3, Ian Collins wrote:
>> On 12/03/2020 08:45, Thiago Adams wrote:
>> > On Wednesday, March 11, 2020 at 4:21:00 PM UTC-3, Ian Collins wrote:
>> >> On 12/03/2020 03:43, Thiago Adams wrote:
>> >>> All these features are my suggestion for the C language.
>> >>
>> >> Why don't you just use a subset of C++ that meets your requirements?
>> >>
>> > 
>> > I think it is an interesting exercise, but the result is not
>> > the same. The other option is to use C.
>> 
>> Not the same as what?
>
> The result is different from my suggestion.

Sometimes you need to be pragmatic to get useful things done.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

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


#150506

FromThiago Adams <thiago.adams@gmail.com>
Date2020-03-12 05:40 -0700
Message-ID<f737a65e-9f46-445e-8f9f-ab22a0f81428@googlegroups.com>
In reply to#150476
On Wednesday, March 11, 2020 at 11:43:33 AM UTC-3, Thiago Adams wrote:
> All these features are my suggestion for the C language.

In case someone is interested:

https://github.com/thradams/c_proposals/blob/master/README.md

I hope to implement these new ideas someday and put online.

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


#150512

Fromchad <cdalten@gmail.com>
Date2020-03-12 13:06 -0700
Message-ID<6ceaea86-8609-40d5-a6fb-9a8c87aa0c65@googlegroups.com>
In reply to#150506
On Thursday, March 12, 2020 at 5:41:08 AM UTC-7, Thiago Adams wrote:
> On Wednesday, March 11, 2020 at 11:43:33 AM UTC-3, Thiago Adams wrote:
> > All these features are my suggestion for the C language.
> 
> In case someone is interested:
> 
> https://github.com/thradams/c_proposals/blob/master/README.md
> 
> I hope to implement these new ideas someday and put online.

Please don't. We already have enough loser languages as it is.

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


#150716

FromPhilipp Klaus Krause <pkk@spth.de>
Date2020-03-22 10:35 +0100
Message-ID<r57bgu$8qo$1@solani.org>
In reply to#150476
Have you had a look at N2494
(http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2494.pdf), which is
another recent proposal to define a common subset of C and C++?

Philipp

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


#150757

FromThiago Adams <thiago.adams@gmail.com>
Date2020-03-23 04:57 -0700
Message-ID<40e54b1f-62bb-4dd7-b0ef-6c891cacce30@googlegroups.com>
In reply to#150716
On Sunday, March 22, 2020 at 6:35:35 AM UTC-3, Philipp Klaus Krause wrote:
> Have you had a look at N2494
> (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2494.pdf), which is
> another recent proposal to define a common subset of C and C++?
> 
Yes. 
Something that catch my attention was lambdas and their usage
with macros to work as functions that can be overrided.

[toc] | [prev] | [standalone]


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


csiph-web