CLASHA - Объектно-ориентированное программирование на Си

Использование и разработка софта (преимущественно на ПЦ)

Moderator: Shaos

User avatar
Stan
Banned
Posts: 397
Joined: 04 Jan 2013 10:09
Location: 95.24.178.158

Post by Stan »

lbodnar wrote:Не для склоки пост сей, а информации ради.
Меня всегда удивляет, что непонятно, в чём причина возникновения подобной склоки!

В общем-то все языки высокого уровня выполняют одну и ту же задачу - превращают свои абстрактные языковые конструкции в код конкретного процессора.

При создании этих языков преследуется цель реально повысить ёмкость информационного слова и дать прогаммисту удобную виртуальную машину, которая позволяла бы не вникать в особенности и структуру конкретной микропроцессорной системы.

Естественно, все удобства ни один язык высокого уровня обеспечить не может, хотя глобальные отличия не так уж и велики.

И что тут может зачастую становиться причиной склоки, а порой и целого холивара, понять порой весьма трудно.

Чаще всего склока начинается с подачи:"а мой любимый язык позволяет сделать это, а твой - так не может"...
User avatar
VituZz
God
Posts: 1343
Joined: 13 Nov 2010 04:06

Post by VituZz »

lbodnar wrote:Вот недавно набрел на вырезанный кусок из интервью с самим создателем, Бйорном Страуструпом. Не знаю, троль или нет.
Ему приписывают высказывание, что язык C++ настолько сложен, что его не знает полностью даже он, его создатель.
Stan wrote:При создании этих языков преследуется цель реально повысить ёмкость информационного слова и дать программисту удобную виртуальную машину, которая позволяла бы не вникать в особенности и структуру конкретной микропроцессорной системы.
Статистика говорит, что число ошибок в коде пропорционально количеству строк кода, и практически не зависит от того, на каком языке написан код. Одна из причин популярности сложных языков в том и состоит, что они позволяют уменьшить число строк кода. Не сам придумал, прочитал у Рэймонда.
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

VituZz wrote:
Stan wrote:При создании этих языков преследуется цель реально повысить ёмкость информационного слова и дать программисту удобную виртуальную машину, которая позволяла бы не вникать в особенности и структуру конкретной микропроцессорной системы.
Статистика говорит, что число ошибок в коде пропорционально количеству строк кода, и практически не зависит от того, на каком языке написан код. Одна из причин популярности сложных языков в том и состоит, что они позволяют уменьшить число строк кода.
Ну а еще "одна из причин популярности сложных языков в том состоит", что они
обеспечивают возможность повторного использования кода, что позволяет осуществлять
кроссплатформенные переносы однажды написанных и хорошо отлаженных программ.
Что, собственно, и заключается в понятии "виртуальная машина".

Хотя многими признаётся, что при всех потугах дела обстоят не так хорошо, как хотелось бы...
iLavr
User avatar
Shaos
Admin
Posts: 24083
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

VituZz wrote:
lbodnar wrote:Вот недавно набрел на вырезанный кусок из интервью с самим создателем, Бйорном Страуструпом. Не знаю, троль или нет.
Ему приписывают высказывание, что язык C++ настолько сложен, что его не знает полностью даже он, его создатель.
Ну создатель создал базу, в которой худо-бедно разбираются почти все C++ программисты, но потом появился "комитет по стандартизации", который за уши притянул кучу разношёрстного барахла типа STL и логика вместе со способностью осилить язык одним человеком стала улетучиваться...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Shaos wrote:Ну создатель создал базу, в которой худо-бедно разбираются почти все C++ программисты, но потом появился "комитет по стандартизации", который за уши притянул кучу разношёрстного барахла типа STL и логика вместе со способностью осилить язык одним человеком стала улетучиваться...
Вряд ли есть люди, которые полностью владеют всеми средствами любого языка.

У MS Word, в отличие от C++, куда как больше пользователей, и то они вряд ли
используют хотя бы треть его возможностей. :lol:


PS. Вот "тёрки" и началииииись.... :wink:
iLavr
User avatar
Shaos
Admin
Posts: 24083
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Возвращаясь обратно - вот очередная итерация (теперь оно называется CLASHA v0.1 : )

Code: Select all

/* clasha.h - classes for pure C by Shaos

 Copyright (c) 2007,2014 A.A.Shabarshin <me@shaos.net>

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
 the rights to use, copy, modify, merge, publish, distribute, sublicense,
 and/or sell copies of the Software, and to permit persons to whom
 the Software is furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.

*/

#ifndef IMPLEMENTATION
#ifdef CLASS
#undef CLASS
#endif
#endif

#ifndef CLASS

#ifndef CLASHA_H
#define CLASHA_H
#include <stdarg.h>
#define CLASHA_VER_STR "v0.1"
#define CLASHA_VER 0x0001 /* (major<<8)|minor */
#define Q(x) #x
#define QQ(x) Q(x)
#define $(x,y) $$(x,_,y)
#define $$(x,y,z) x##y##z
#define NEW(x) $(new,x)
#define DEL(x) $(del,x)
#define BAD(x) $(bad,x)
#define SET(x) $(set,x)
#define CON(x) $(x,con)
#define CONS(x) $(x,cons)
#define DES(x) $(x,des)
#define HASH(x) $(x,hash)
#ifdef LIGHT
#define CLASS_BEGIN(x) typedef struct $(t,x) {
#else
#define CLASS_BEGIN(x) typedef struct $(t,x) { int _h_,_n_;
#ifdef HEAVY
#ifdef __cplusplus
extern "C" {
#endif
/* optional class registration for delete method */
void register_class(int h,void(*f)(void*));
/* optional common delete that will call proper method */
void common_delete(void *p);
#ifdef __cplusplus
}
#endif
#define delete(x) common_delete(x)
#endif
#endif
#define CLASS_END(x) } x;
#ifdef __cplusplus
#define PUBLIC extern "C"
#else
#define PUBLIC extern
#endif
#define METHOD(x) $(CLASS,x)
#define STATIC(x) $(CLASS,x)
#define VIRTUAL(x) (*x)
#define BEGIN CLASS_BEGIN(CLASS)
#define END CLASS_END(CLASS) \
 PUBLIC void CON(CLASS) (CLASS*,int,...); \
 PUBLIC void CONS(CLASS) (CLASS*,int,va_list); \
 PUBLIC void DES(CLASS) (CLASS*); \
 PUBLIC CLASS* NEW(CLASS) (int,...); \
 PUBLIC void DEL(CLASS) (void*); \
 PUBLIC int BAD(CLASS) (CLASS*);
#endif

#else

#include <stdlib.h>

/* private methods */

#ifndef LIGHT
int HASH(CLASS) = 0;

void SET(CLASS) (CLASS* p)
{
 int c,h=0;
 char *o,s[] = QQ(CLASS);
 if(!HASH(CLASS))
 {
   o = s;
   while((c=*o++)) h += (h<<5) + c;
   HASH(CLASS) = h;
 }
 p->_h_ = HASH(CLASS);
}
#endif

/* public methods */

int BAD(CLASS) (CLASS* p)
{
#ifndef LIGHT
 if(HASH(CLASS)!=p->_h_) return -1;
#endif
 return 0;
}

void CON(CLASS) (CLASS *p, int t, ...)
{
 va_list a;
#ifndef LIGHT
 SET(CLASS) (p);
#endif
 va_start(a,t);
 CONS(CLASS) (p,t,a);
 va_end(a);
}

CLASS* NEW(CLASS) (int t, ...)
{
 int i;
 CLASS* p;
 p = (CLASS*)malloc(sizeof(CLASS)*((t>0)?(size_t)t:1));
 if(p)
 {
  if(t > 0) /* array */
  {
    for(i=0;i<t;i++)
    {
      CON(CLASS) (&p[i],0);
#ifndef LIGHT
      p[i]._n_ = t - i;
#endif
    }
  }
  else
  {
    va_list a;
    va_start(a,t);
#ifndef LIGHT
    SET(CLASS) (p);
#endif
    CONS(CLASS) (p,t,a);
    va_end(a);
#ifndef LIGHT
    p->_n_ = 1;
#endif
  }
#ifndef LIGHT
#ifdef HEAVY
  register_class(p->_h_,DEL(CLASS));
#endif
#endif
 }
 return p;
}

void DEL(CLASS) (void* v)
{
 CLASS* p = (CLASS*)v;
#ifndef LIGHT
 int i,n = p->_n_;
 if(BAD(CLASS)(p))
 {
    exit(-1);
 }
#endif
 DES(CLASS) (p);
#ifndef LIGHT
 p->_h_ = 0;
 for(i=1;i<n;i++)
 {
   DES(CLASS) (&p[i]);
   p[i]._h_ = 0;
 }
#endif
 free(p);
}

#undef CLASS

#endif
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24083
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Итак, имеется 3 режима:
- LIGHT (требуется опция сборки -DLIGHT) - при этом создаются простые структуры (как в примере в начале топика) без оверхеда;
- NORMAL (режим по умолчанию) - при этом в начале каждого объекта есть 2 инта - хеш класса и кол-во объектов по этому указателю (оверхед 8 байт на объект);
- HEAVY (требуется опция сборки -DHEAVY и файл clasha.c) - как NORMAL, но с возможностью удалять динамически созданные объекты с помощью одной функции delete (корректно удаляются как единичные объекты, так и массивы объектов с вызовом нужного количества деструкторов).
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24083
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Пример класса - class_mya.h:

Code: Select all

#ifndef CLASS_MYA_H
#define CLASS_MYA_H

#include "clasha.h"

#define CLASS MyClassA

BEGIN
 int id2;
 char str[10];
 int VIRTUAL(area) (void*);
END

#define MY_CLASSA_DEFAULT    0
#define MY_CLASSA_CHARP     -1
#define MY_CLASSA_CHARP_INT -2

PUBLIC void METHOD(print) (CLASS *this);

PUBLIC int STATIC(value);

#endif
его имплементация - class_mya.c:

Code: Select all

#include <stdio.h>
#include <string.h>

#include "class_mya.h" /* my class */

#define IMPLEMENTATION

#include "clasha.h" /* bodies */

int $(MyClassA,area) (void* vthis)
{
 MyClassA* this = vthis;
 return this->id2*(int)strlen(this->str);
}

void $(MyClassA,cons) (MyClassA* this, int t, va_list a)
{
 if(t<=MY_CLASSA_DEFAULT)
 {
    *this->str = 0;
    this->id2 = 0;
    this->area = $(MyClassA,area);
 }
 if(t<=MY_CLASSA_CHARP)
 {
    strncpy(this->str,va_arg(a,char*),10);
    this->str[9] = 0;
 }
 if(t<=MY_CLASSA_CHARP_INT)
 {
    this->id2 = va_arg(a,int);
 }
}

void $(MyClassA,des) (MyClassA* this)
{
 (void)this;
}

void $(MyClassA,print) (MyClassA* this)
{
 printf("id=%i str='%s'\n",this->id2,this->str);
}

int $(MyClassA,value) = 0;
использование в большой программе:

Code: Select all

 MyClassA obj2,*pobj2,*pobj3;

 $(MyClassA,con) (&obj2,MY_CLASSA_CHARP,"test3");
 $(MyClassA,print) (&obj2);
 $(MyClassA,des) (&obj2);

 pobj2 = new_MyClassA(MY_CLASSA_CHARP_INT,"test4",-2);
 $(MyClassA,print) (pobj2);
#ifdef HEAVY
 delete(pobj2);
#else
 del_MyClassA(pobj2);
#endif

 pobj3 = new_MyClassA(3);
 $(MyClassA,print) (&pobj3[0]);
 $(MyClassA,print) (&pobj3[1]);
 $(MyClassA,print) (&pobj3[2]);
#ifdef HEAVY
 delete(pobj3);
#else
 del_MyClassA(pobj3);
#endif
Обратите внимание на последний пример (как и в C++ если создаём динамический массив, то используется только конструктор по умолчанию) - в режиме LIGHT будет вызван только один деструктор для самого первого объекта (с индексом 0), т.к. функция del_MyClassA не будет знать сколько объектов выделено на указателе, т.е. в режиме LIGHT нельзя создавать динамические массивы объектов, у которых непустые деструкторы...

P.S. Запись вида $(class,method) превращается препроцессором в class_method, т.е. можно писать и так, и эдак, однако с $ веселее :)
Знак доллара не поддерживается в стандарте ANSI-C, но поддерживается в GCC и в некоторых старых компиляторах C...

P.P.S. Полный набор файлов на поиграца брать тут: http://nedopc.org/nedopc/files/clasha1.zip (5K)
Last edited by Shaos on 12 Oct 2014 22:02, edited 3 times in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24083
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Теперь на CLASHA (который по сути можно считать новым языком программирования с синтаксисом си ; ) надо создать все основные фенечки C++ как то vector, list, slist, queue, deque, map, set и т.д. плюс можно сделать свою ООП надстройку над pthreads для параллельного программирования, а также библиотеку виджетов для построения пользовательских интерфейсов в растре...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24083
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

"Объектно-ориентированное программирование это дорогая катастрофа, которая должна закончится":

http://www.smashcompany.com/technology/ ... h-must-end

P.S. Автор агитирует за функциональный подход...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Shaos wrote:"Объектно-ориентированное программирование это дорогая катастрофа, которая должна закончится"...
Мне вот было очень интересно, когда я с этим разбирался, - а как выглядит объект в машинном коде?

Потому что во многих книгах начинают пудрить мозг некоторыми не совсем приятными аналогиями типа:
"Представьте себе яблоко, у него есть свойства: форма, цвет ... и т.д."

Мне это представляется совсем никуда не годной абстракцией с точки зрения программиста.

Потому как, к примеру, окно Винды - это тоже в некотором роде объект, но я неплохо представляю,
как это выглядит на ассемблере...

А вот ты мог бы привести простой пример, как некий объект реализуется в машинном коде?
Кого не спрашивал - все скатываются к "яблокам"... :-?
Last edited by Lavr on 15 Jan 2016 12:56, edited 2 times in total.
iLavr
jdigreze
God
Posts: 1388
Joined: 02 Jan 2006 02:28
Location: Abakan

Post by jdigreze »

Если в общем виде - упорядоченная структура ссылок и связанных с ними переменных. При создании объекта, выделяется память на структуру, заполняются ссылки на функции, инициализируются некоторые связанные переменные, в таблицу объектов данного класса добавляется ссылка на эту структуру, потом вызывается функция конструктора, если определена, и конструктор умолчаний, инициализирующий ещё некий объём переменных.

Есть некоторые исключения и отклонения, связанные с конкретной реализацией компилятора.

Вообще, ООП недолюбливают из-за некоторых программистов, пишущих абстракции там где не нужно.
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Lavr wrote:...привести простой пример, как некий объект реализуется в машинном коде?
jdigreze wrote:Если в общем виде - упорядоченная структура ссылок и связанных с ними переменных. При создании объекта, выделяется память на структуру, заполняются ссылки на функции, инициализируются некоторые связанные переменные, в таблицу объектов данного класса добавляется ссылка на эту структуру, потом вызывается функция конструктора, если определена, и конструктор умолчаний, инициализирующий ещё некий объём переменных.
Вот это я и называю:
Lavr wrote:Кого не спрашивал - все скатываются к "яблокам"... :-?
Я и сам могу написать похожую общую фразу, ради неё я бы не спрашивал...
iLavr
jdigreze
God
Posts: 1388
Joined: 02 Jan 2006 02:28
Location: Abakan

Post by jdigreze »

А чего там интересного в машинном коде по твоему должно быть? Просто набор цифр размерностей byte,word,dword и т.п. Причём это всё появляется динамически при создании объектов, и с ходу дебагером не так просто отловить куда в памяти это попало.
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

jdigreze wrote:А чего там интересного в машинном коде по твоему должно быть?

А интересного там вот что, на мой взгляд: как ни крути, в кодах процессор работает всё же линейно.
А вот объекты - это просто еще один уровень абстракции над машинным кодом, что, впрочем,
присуще любому ЯВУ.

Но ты ещё забыл, что ещё есть и методы.

Так вот мне просто интересно увидеть это конкретно - я так обычно лучше понимаю, как это всё взаимодействует,
нежели, когда всё объясняют абстрактными понятиями типа "каналы... потоки..." и т.д.

Я и сам понимаю, что дебагером это ловить и непросто да и глупо...
Просто люди сочинившие ООП или хорошо знающие ООП должны, видимо, представлять, как это выглядит в коде?

Мне бы достаточно было бы простого примера, но чтобы конкретно увидеть, как объект формируется и как все
его "прибамбасы" выглядят на низком уровне.

Именно мне и интересно - как это всё конкретно "появляется динамически при создании объектов" (и как исчезает - тоже)... 8)

Заодно, кстати: а как ты представляешь себе, выглядит в коде очередь сообщений Винды?
iLavr