LINUX.ORG.RU

Существует ли язык высокого уровня, который устойчиво быстрее C?

 ,


0

1

Возможно ли сделать язык программирования, который не будет содержать платформ-зависимых операций, но при этом позволит получить у готовой программы производительность не меньше чем у оптимально написанной программы на C?

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

Так вот, возможно ли сделать такой язык? Если да, то в каком направлении копать?

А может уже существуют такие языки, просто из-за популярности C на них мало кто пишет, поскольку всплывают проблемы совместимости с существующей базой уже готового кода?

★★★★★
Ответ на: комментарий от anonymous

Так покажи. Покажи код, который быстрее решения с использованием стандартных средств.

anonymous
()
Ответ на: комментарий от anonymous

Так покажи. Покажи код, который быстрее решения с использованием стандартных средств.

Я понятия не имею что для тебя «решение с использование стандартных средств» :-)

anonymous
()
Ответ на: комментарий от anonymous

Смотри сюда. Из «стандартных» решений есть лептоника. Ту же самую задачу выделения 4-х и 8-ми связных областей она решает как минимум в 5 раз медленнее!!!

anonymous
()
Ответ на: комментарий от anonymous

Просто покажи код, к которому применимо то, о чем ты говоришь.

Ну хорошо :-) Пусть требуется удалить все пробелы по краям строки перед выводом её на экран :-) Для этого был написан простой велосипед, который в нижеследующем тесте запускается 10 миллионов раз:

/* (C) :-) */
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* My bicycle :-) */
static char *trim(char *s)
{
     while (isspace(*s)) ++s;
     int l;
     if ((l = strlen(s)) > 0) {
          char *e = s + l - 1;
          while (isspace(*e)) --e;
          e[1] = '\0';
     }
     return s;
}

int main(int argc, char *argv[])
{
     char *const test = strdup("       :-) :-)                   ");
     const char *trims;
     for (int i = 0; i < 10000000; ++i)
           trims = trim(test);
     printf("%s\n", trims);
     free(test);
     return 0;
}

А это решение с использованием «стандартного средства» - великого и ужасного boost, которое также запускается 10 миллионов раз:

// (C) :-)
#include <boost/algorithm/string/trim.hpp>

#include <iostream>
#include <string>

int main(int argc, char *argv[])
{
  std::string test("       :-) :-)                   ");
  for (int i = 0; i < 10000000; ++i)
    boost::algorithm::trim(test);
  std::cout << test << std::endl;
  return 0;
}
Данное сравнение не честно по отношению к моему велосипеду на C, потому что мой велосипед честно триммирует строку все 10 миллионов итераций, в то время как версия на C++ триммирует строку только на 1-й итерации :-) Чтобы заставить цепепешную версию с использованием вышеупомянутых «стандартных» готовых средств триммировать строку 10 миллионов итераций, копирования не избежать, т.е. это либо boost::algorithm:trim_copy, либо копирование строки перед передачей ссылки на неё в boost::algorithm::trim :-) Но это будет такой тормоз, что 10 миллионов итераций я ждать не хочу :-) Поэтому я сжалился над цепепешной версией и оставил так, как есть :-) Результаты:
tests $ gcc -O3 -otrim trim.c
tests $ g++ -O3 -otrim+ trim.cpp
tests $ time ./trim
:-) :-)

real	0m0.205s
user	0m0.200s
sys	0m0.000s
tests $ time ./trim+
:-) :-)

real	0m1.341s
user	0m1.336s
sys	0m0.004s
Стандартное решение из великого boost слило моему велосипеду в 6 раз :-) Бугага :-)

anonymous
()
Ответ на: комментарий от anonymous

Стандартное решение из великого boost слило моему велосипеду в 6 раз :-) Бугага :-)

А ты действительно веселый дурачок. Аналог твоего кода на бусте будет trim_if(test, isspace). А теперь еще раз сравни.

anonymous
()
Ответ на: комментарий от anonymous

Аналог твоего кода на бусте будет trim_if(test, isspace). А теперь еще раз сравни.

Ой, точно, просто не стал читать, чтобы понять, что есть trim_if вот это:

namespace boost {
  namespace algorithm {
    template<typename OutputIteratorT, typename RangeT, typename PredicateT> 
      OutputIteratorT 
      trim_left_copy_if(OutputIteratorT, const RangeT &, PredicateT);
    template<typename SequenceT, typename PredicateT> 
      SequenceT trim_left_copy_if(const SequenceT &, PredicateT);
    template<typename SequenceT> 
      SequenceT trim_left_copy(const SequenceT &, 
                               const std::locale & = std::locale());
    template<typename SequenceT, typename PredicateT> 
      void trim_left_if(SequenceT &, PredicateT);
    template<typename SequenceT> 
      void trim_left(SequenceT &, const std::locale & = std::locale());
    template<typename OutputIteratorT, typename RangeT, typename PredicateT> 
      OutputIteratorT 
      trim_right_copy_if(OutputIteratorT, const RangeT &, PredicateT);
    template<typename SequenceT, typename PredicateT> 
      SequenceT trim_right_copy_if(const SequenceT &, PredicateT);
    template<typename SequenceT> 
      SequenceT trim_right_copy(const SequenceT &, 
                                const std::locale & = std::locale());
    template<typename SequenceT, typename PredicateT> 
      void trim_right_if(SequenceT &, PredicateT);
    template<typename SequenceT> 
      void trim_right(SequenceT &, const std::locale & = std::locale());
    template<typename OutputIteratorT, typename RangeT, typename PredicateT> 
      OutputIteratorT 
      trim_copy_if(OutputIteratorT, const RangeT &, PredicateT);
    template<typename SequenceT, typename PredicateT> 
      SequenceT trim_copy_if(const SequenceT &, PredicateT);
    template<typename SequenceT> 
      SequenceT trim_copy(const SequenceT &, 
                          const std::locale & = std::locale());
    template<typename SequenceT, typename PredicateT> 
      void trim_if(SequenceT &, PredicateT);
    template<typename SequenceT> 
      void trim(SequenceT &, const std::locale & = std::locale());
  }
}
Быстрее было написать на C :-) И это не аналог, т.к. trim_if() триммирует 1 раз, а мой велосипед - все 10 миллионов итераций :-) И всё равно, цепепе слил, даже здесь:
tests $ time ./trim
:-) :-)

real	0m0.148s
user	0m0.148s
sys	0m0.000s
tests $ time ./trim+
:-) :-)

real	0m0.193s
user	0m0.192s
sys	0m0.000s

anonymous
()
Ответ на: комментарий от anonymous

Ой, точно, просто не стал читать, чтобы понять, что есть trim_if вот это:

Ты просто не стал читать. В доке написано про _if варианты.

Быстрее было написать на C :-)

Ага, каких-то «10 минут» (с) для простой задачи, что может быть быстрее.

И это не аналог, т.к. trim_if() триммирует 1 раз, а мой велосипед - все 10 миллионов итераций :-)

Т.е. ты сам в своем коде не видишь изменение оригинальной строки?

И всё равно, цепепе слил, даже здесь:

У тебя ус отклеился время изменилось с предыдущего поста. У меня практически вровень, плюс-минус погрешность.

anonymous
()
Ответ на: комментарий от anonymous

Ага, каких-то «10 минут» (с) для простой задачи, что может быть быстрее.

1 минута :-)

Т.е. ты сам в своем коде не видишь изменение оригинальной строки?

Это ты не видишь, что в моём коде в trim() каждый раз передаётся оригинальная строка - test :-)

У тебя ус отклеился время изменилось с предыдущего поста. У меня практически вровень, плюс-минус погрешность.

Так я же и тест-кейс на C изменил, чтобы он соответствовал тест-кейсу на цепепе :-) Благо це это позволяет, в отличии от цепепе:

/* (C) :-) */
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* My bicycle :-) */
static inline char *trim(char *s)
{
     while (isspace(*s)) ++s;
     int l;
     if ((l = strlen(s)) > 0) {
          char *e = s + l - 1;
          while (isspace(*e)) --e;
          e[1] = '\0';
     }
     return s;
}

int main(int argc, char *argv[])
{
     char *const test = strdup("       :-) :-)                   ");
     char *trims = test;
     for (int i = 0; i < 10000000; ++i)
           trims = trim(trims);
     printf("%s\n", trims);
     free(test);
     return 0;
}
Теперь тест-кейсы эквивалентны :-) Возьми и запусти :-) И кто из нас дурачок? :-)

anonymous
()
Ответ на: комментарий от anonymous

1 минута :-)

Ты скромничаешь.

Это ты не видишь, что в моём коде в trim() каждый раз передаётся оригинальная строка - test :-)

А это что:

e[1] = '\0';

Т.е. ты сам не разбираешься в предрставленном коде. Скопипастил небось.

Возьми и запусти :-)

Все так же без разницы, около 0.17-0.18 сек на оба варианта.

И кто из нас дурачок? :-)

Спросим у зрительного зала.

anonymous
()
Ответ на: комментарий от anonymous

Ты скромничаешь.

Ну я скромен :-)

А это что: e[1] = '\0';

Это запись по адресу, на который указывает e + 1 :-) Теперь открой глаза и подумай :-)

Все так же без разницы, около 0.17-0.18 сек на оба варианта.

Не мои проблемы :-)

Спросим у зрительного зала.

Гыгы :-)

anonymous
()
Ответ на: комментарий от anonymous

Это запись по адресу, на который указывает e + 1 :-) Теперь открой глаза и подумай :-)

Ну вот ты и скатился в откровенную клоунаду.

Не мои проблемы :-)

Конечно. Все хорошо.

anonymous
()
Ответ на: комментарий от anonymous

Это запись по адресу, на который указывает e + 1 :-) Теперь открой глаза и подумай :-)

А смайлик-то еще больший идиот, чем можно было себе представить:

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* My bicycle :-) */
static inline char *trim(char *s)
{
     while (isspace(*s)) ++s;
     int l;
     if ((l = strlen(s)) > 0) {
          char *e = s + l - 1;
          while (isspace(*e)) --e;
          e[1] = '\0';
     }
     return s;
}

int main(int argc, char *argv[])
{
     char *const test = strdup("       :-) :-)                   ");
     char *trims = test;
     trims = trim(trims);
     printf("trims: '%s', test: '%s'\n", trims, test);
     free(test);
     return 0;
}
Результат: trims: ':-) :-)', test: ' :-) :-)'

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

Ну вот ты и скатился в откровенную клоунаду.

А что не так? :-) Ещё раз повторяю - строка оригинальная :-) Мало ли что в адресе, на который указывает e + 1 после 1-й итерации будет 0 :-) Ну ладно, не парься :-) В моей версии после первой итерации алгоритм будет усекать лишь те пробелы, что слева :-) Но строка всё равно оригинальная, в широком смысле :-) Гг :-)

Конечно. Все хорошо.

Конечно цепепе слил :-) На моё компе это так :-)

anonymous
()
Ответ на: комментарий от eao197

А смайлик-то еще больший идиот, чем можно было себе представить

Полёт твоей фантазии велик :-) Правда только в твоих фантазиях :-) Гг :-)

anonymous
()
Ответ на: комментарий от anonymous

Но строка всё равно оригинальная, в широком смысле :-) Гг :-)

В варианте с boost - аналогично.

Конечно цепепе слил :-) На моё компе это так :-)

Мои поздравления.

anonymous
()
Ответ на: комментарий от anonymous

Мои фантазии оставьте мне. А вот то, что вы агитируете за С, при этом нормально на C писать не можете... Вот это что? Заблуждение или диагноз?

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

Ты умудрился слить даже в задаче, которую сам привел. Жесть.

Ещё один поциент :-) Ну и где же слив? :-)

anonymous
()
Ответ на: комментарий от anonymous

В варианте с boost - аналогично.

Т.е. я на уровне с разработчиками boost :-)

Мои поздравления.

Вау, спасибо! :-)

anonymous
()
Ответ на: комментарий от anonymous

И что в моём коде не так? :-)

Вы модифицировали исходную строку и даже не замечали этого, пока вас не ткнули в ваш же код носом.

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

Ну и где же слив? :-)

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

Так ответь, зачем велосипедить?

anonymous
()
Ответ на: комментарий от eao197

Вы модифицировали исходную строку и даже не замечали этого, пока вас не ткнули в ваш же код носом.

Бугага :-) Я не замечал, что модифицирую исходную строку? :-) Ты глянь, реально клоун :-) Думает, что я написал сигнатуру trim(char *), а не trim(const char*) и не замечал, что модифицирую память по указателю не на константу :-) Тебя от 20 лет цепепе совсем что-ли повело? :-)

anonymous
()
Ответ на: комментарий от anonymous

Во-первых, код - говно.

Почему он говно? :-) Обоснуй, иначе слив :-)

Во-вторых, он портит вход.

Слив засчитан :-) Он это делает для эффективности :-) Как это делает и trim/trim_if из boost :-)

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

Слив засчитан :-) Я привёл результаты :-)

Так ответь, зачем велосипедить?

Слив засчитан :-)

anonymous
()
Ответ на: комментарий от anonymous

Слив засчитан :-)

Ты струсил даже опубликовать рядом два варианта кода, которые мерял.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Бугага :-) Я не замечал, что модифицирую исходную строку? :-)

Более того, вы даже не заметили, как сами это признали:

А что не так? :-) Ещё раз повторяю - строка оригинальная :-) Мало ли что в адресе, на который указывает e + 1 после 1-й итерации будет 0 :-) Ну ладно, не парься :-) В моей версии после первой итерации алгоритм будет усекать лишь те пробелы, что слева :-) Но строка всё равно оригинальная, в широком смысле :-) Гг :-)

Как раз то, что вы сделали реализацию теста, после первой же итерации переходящую всего лишь в замеры trim_left, говорит о вас больше, чем вам хотелось бы.

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

Почему он говно? :-)

Ну, например, из-за strlen. На больших строках твоя функция просядет и будет бесполезно лопатить память.

Как это делает и trim/trim_if из boost :-)

В boost есть еще и _copy варианты.

// Другой Анонимус

anonymous
()
Ответ на: комментарий от eao197

Более того, вы даже не заметили, как сами это признали:

Слив засчитан :-) Вот оно, влияние цепепе :-) Повторяю ещё раз - строка оригинальная - т.е. это строка, которую высрал strdup() :-) И то, что в e + 1 записался 0 не привело к переаллокации памяти :-) Строка оригинальная :-)

Как раз то, что вы сделали реализацию теста, после первой же итерации переходящую всего лишь в замеры trim_left, говорит о вас больше, чем вам хотелось бы.

И даже при таких замерах boost слил смайлику :-)

anonymous
()
Ответ на: комментарий от anonymous

Ну, например, из-за strlen. На больших строках твоя функция просядет и будет бесполезно лопатить память.

Давай пруф :-)

В boost есть еще и _copy варианты.

Я об этом говорил :-) Или читай весь тред, или не впрягайся со своими взвяками :-)

anonymous
()
Ответ на: комментарий от anonymous

Строка оригинальная :-)

Вы настолько тупы безграмотны, что не различаете «буфер» и «строку». Буфер у вас один и тот же (даже непонятно, зачем вообще нужен был strdup и последующий free). А вот строка поменялась после переноса терминального ноль-символа.

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

Давай пруф :-)

Пруф чего? Того, что время работы strlen зависит от длины строки? Ну вот, например:

https://www.gnu.org/software/m68hc11/examples/bench-string.html

Явно виден линейный рост.

Я об этом говорил :-) Или читай весь тред, или не впрягайся со своими взвяками :-)

Ты об этом говорил, а в boost уже есть. В итоге ты будешь опять велосипедить.

anonymous
()
Ответ на: комментарий от eao197

Вы настолько тупы безграмотны, что не различаете «буфер» и «строку».

Причём тут буфер? :-) Я пользовался strdup(), а не каким-то bufdup() :-)

(даже непонятно, зачем вообще нужен был strdup и последующий free)

Слив засчитан :-) А теперь я тебе, безграмотному цепепешнику объясню зачем я это сделал :-) Сейчас ты попался на том, что без strdup() функция trim() попыталась записать в константу и получился бы Segmentation fault :-) А free() нужен чтобы память освободить несмотря на то, что это перед завершением программы :-) Ты обделался :-)

А вот строка поменялась после переноса терминального ноль-символа.

Поменялось содержимое e + 1 :-)

anonymous
()
Ответ на: комментарий от eao197

У тебя на него персональный разрыв пукана? Тогда все ясно.

anonymous
()
Ответ на: комментарий от anonymous

Причём тут буфер?

При том, что строка в C — это всего лишь последовательность символов в памяти, завершающаяся терминальным ноль символом. Соответственно, под хранение строки должна быть выделена какая-то память. Кусок этой памяти будет тем самым буфером, хранящим строку.

К strdup или bufdup это не имеет никакого отношения.

А теперь я тебе, безграмотному цепепешнику объясню зачем я это сделал :-) Сейчас ты попался на том, что без strdup() функция trim() попыталась записать в константу и получился бы Segmentation fault :-)

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

char test[] = "bu-ga-ga :)";
char * trims = test;
И константность в вашем примере идет лесом, так что вы вообще зря ее привлекли.

Поменялось содержимое e + 1 :-)

Матчасть поучите. Может поймете, как эта конструкция влияет на значение строки.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

При том, что строка в C — это всего лишь последовательность символов в памяти, завершающаяся терминальным ноль символом.

Не надо мне это говно рассказывать :-) Я знаю эту всю хрень :-)

Соответственно, вы могли бы обойтись размещением буфера для хранения строки просто на стеке:

Так сделать можно :-)

И константность в вашем примере идет лесом, так что вы вообще зря ее привлекли.

Слив засчитан :-) Попробуй вызови trim(" :-) :-) ") :-)

Матчасть поучите. Может поймете, как эта конструкция влияет на значение строки.

Бугага :-)

anonymous
()
Ответ на: комментарий от anonymous

Слив засчитан :-) Попробуй вызови trim(" :-) :-) ") :-)

Смайлик, вы, блин, реально не видите разницы между константным указателем на неконстантную строку (тот самый char *const test = strdup из вашего первоначального примера) и указателем на константную строку?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Смайлик, вы, блин, реально не видите разницы между константным указателем на неконстантную строку (тот самый char *const test = strdup из вашего первоначального примера)

*const test тут потому, что я не собирался менять test - т.е. указатель :-)

и указателем на константную строку?

Фух :-) Это ты не догоняешь :-) Попробуй сделать так:

"Zhopa"[1] = 0;

Скорее всего, словишь SIGSEGV :-)

anonymous
()
Ответ на: комментарий от anonymous

Скорее всего, словишь SIGSEGV :-)

Етить-колотить... Хорошо хоть, что эта тема позволила выяснить, что царь — шизофреник, а смайлик — идиот.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Етить-колотить... Хорошо хоть, что эта тема позволила выяснить, что царь — шизофреник, а смайлик — идиот.

Чтобы полностью выяснить кто есть кто, советую желающим запустить такую вот программку :-)

/* (C) :-) */
void test(char *s)
{
     s[1] = 0;
}

int main(int argc, char *argv[])
{
     test("Idiot tut ty");
     return 0;
}

Для ленивых вот результат на Linux:

tests $ gcc -O3 -oidiot idiot.c
tests $ ./idiot
Segmentation fault

Шёл бы ты лесом медленным шагом :-)

anonymous
()
Ответ на: комментарий от anonymous

в С++ получишь ошибку на этапе компиляции.

Хрен в стакан:

tests $ g++ -O3 -oidiot idiot.c
idiot.c: In function ‘int main(int, char**)’:
idiot.c:9:25: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
      test("Idiot tut ty");
                         ^
tests $ ./idiot
Segmentation fault

Цепепе :-)

anonymous
()
Ответ на: комментарий от anonymous

Хрен в стакан:

Актуальный стандарт С++ запрещает такое преобразование, твой gcc, очевидно либо по дефолту использует С++03, либо нарушает стандарт.

anonymous
()
Ответ на: комментарий от anonymous

Актуальный стандарт С++ запрещает такое преобразование, твой gcc, очевидно либо по дефолту использует С++03, либо нарушает стандарт.

Важно то, что происходит в действительности, а не то, что в мечтах всяких комитетов по стандартизации :-) Реальный мир отличается от представлений о том, каким он должен быть :-)

anonymous
()
Ответ на: комментарий от anonymous

Важно то, что происходит в действительности, а не то, что в мечтах всяких комитетов по стандартизации :-) Реальный мир отличается от представлений о том, каким он должен быть :-)

В действительности -Werror обломает компиляцию. И, не знаю как ты, а я использую этот флаг.

anonymous
()
Ответ на: комментарий от anonymous

gcc, очевидно либо по дефолту использует С++03

Пожалуйста, цепепе-14:

tests $ g++ -std=c++14 -O3 -oidiot idiot.c
idiot.c: In function ‘int main(int, char**)’:
idiot.c:9:25: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
      test("Idiot tut ty");
                         ^
tests $ ./idiot
Segmentation fault

anonymous
()
Ответ на: комментарий от anonymous

В действительности -Werror обломает компиляцию. И, не знаю как ты, а я использую этот флаг.

Молодец :-) В маленьком проекте под конкретную платформу этот флаг использовать лучше, чем не использовать :-)

anonymous
()
Ответ на: комментарий от anonymous

Ч.Т.Д.

tests $ ./idiot
Segmentation fault

Ч. т. д. :-)

anonymous
()
Ответ на: комментарий от anonymous

Молодец :-) В маленьком проекте под конкретную платформу этот флаг использовать лучше, чем не использовать :-)

Тонко, но мои проекты обычно работают минимум на трех платформах, и они достаточно большие. И именно потому я не пропускаю предупреждения от компиляторов.

anonymous
()
Ответ на: комментарий от anonymous

Актуальный стандарт С++ запрещает такое преобразование, твой gcc, очевидно либо по дефолту использует С++03, либо нарушает стандарт.

GCC 5.2/5.3 и clang 3.7.1 выдают предупреждение на этот код (причем как в C++03, так и в C++14). VC++14.0 проглатывает код без предупреждений даже с -W4.

Полагаю, с принятием C++17 это предупреждение в gcc/clang будет заменено ошибкой. А в VC++ фронт-энд компилятора уже полностью заменят на clang к тому времени.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

GCC 5.2/5.3 и clang 3.7.1 выдают предупреждение на этот код (причем как в C++03, так и в C++14). VC++14.0 проглатывает код без предупреждений даже с -W4.

Очевидно забота об обратной совместимости. Зря как по мне. Ну и к слову, оригинальный пример, который я комментировал, таки не собирается:

error: read-only variable is not assignable
     "Zhopa"[1] = 0;
     ~~~~~~~~~~ ^
anonymous
()
Ответ на: комментарий от anonymous

оригинальный пример, который я комментировал, таки не собирается:

Надо же, компилятор цепепе смог понять, что скомпилировать «Zhopa»[1] = 0 нельзя, а передать «Zhopa» в f(char *) - это можно :-) Отлично, чо :-)

anonymous
()
Ответ на: комментарий от anonymous

Надо же, компилятор цепепе смог понять, что скомпилировать «Zhopa»[1] = 0 нельзя, а передать «Zhopa» в f(char *) - это можно :-) Отлично, чо :-)

Компилятор и второй случай понял, иначе бы не выдал предупреждение. Причем, повторюсь, стандарт требует ошибку. Так что С++ понемногу избавляется от наследия С, где оба варианта молча прокатят, но не так быстро как хотелось бы.

anonymous
()
Ответ на: комментарий от anonymous

Компилятор и второй случай понял, иначе бы не выдал предупреждение.

Он его не понял :-) Если бы он его понял, то не допустил бы на выходе программу, которая приводит к segmentation fault :-) А если понял, но допустил такой облом, то грош цена такой компиляции :-)

anonymous
()
Ответ на: комментарий от anonymous

Чтобы ты понял, что компилятор не понимает сути проблемы, скорми ему такой код:

/* (C) :-) */

void test(char* s)
{
  s[1] = 0;
}

int main(int argc, char *argv[])
{
  test(const_cast<char*>("blabla"));
  return 0;
}

Этот тупорез не понимает, что const_cast делается на указателе на память только для чтения :-)

anonymous
()
Ответ на: комментарий от anonymous

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

Привязяв строковые литералы к STL string? Гениально.

anonymous
()
Ответ на: комментарий от anonymous

И вообще, ну нахрен эти бусты и велосипеды на C:

CL-USER> (time (loop for i from 1 to 10000000 do (string-trim " " "    :-) :-)      ")))
Evaluation took:
  0.877 seconds of real time
  0.940000 seconds of total run time (0.940000 user, 0.000000 system)
  107.18% CPU
  2,012,556,493 processor cycles
  0 bytes consed
  
NIL

Вот оно моё :-)

anonymous
()
Ответ на: комментарий от anonymous

А если понял, но допустил такой облом, то грош цена такой компиляции :-)

И это говорит человек, который пробовал писать на С и gcc? :)

Этот тупорез не понимает, что const_cast делается на указателе на память только для чтения :-)

И опять ты сел в лужу. Это на твоей платформе будет такое поведение. А на какой-нибудь непопсовой платформе это может быть вполне себе рабочий трюк. Потому каст будет работать в любом случае, это уже ответственность программиста.

anonymous
()
Ответ на: комментарий от anonymous

Привязяв строковые литералы к STL string? Гениально.

Ты вообще о чем? Во-первых string не часть STL. Во-вторых никакой привязки нет в принципе.

anonymous
()
Ответ на: комментарий от anonymous

Во-первых string не часть STL.

Действительно, почему-то его не относят к STL (но относят к standard C++ library).

Во-вторых никакой привязки нет в принципе.

Ну и как мне использовать сишные строки без обёрток? ISO C++ forbids converting a string constant to ‘char*’ же.

anonymous
()
Ответ на: комментарий от anonymous

И это говорит человек, который пробовал писать на С и gcc? :)

И который оценил качество компиляторов C и C++ :-)

И опять ты сел в лужу.

Ой ли? :-)

Это на твоей платформе будет такое поведение.

Другие платформы меня не заботят :-) Вообще, никак :-)

А на какой-нибудь непопсовой платформе это может быть вполне себе рабочий трюк.

Смешной какой :-) Трюк записи в константу :-) Бугага :-)

Потому каст будет работать в любом случае, это уже ответственность программиста.

Грош цена такой компиляции и таким компилятором, опять же :-)

anonymous
()
Ответ на: комментарий от anonymous

Это вам не «тормозной» boost ;)

Это тебе не ущербненький цепепе :-)

anonymous
()
Ответ на: комментарий от anonymous

Ну и как мне использовать сишные строки без обёрток? ISO C++ forbids converting a string constant to ‘char*’ же.

Нельзя кастить константу в неконстантный указатель. И не больше. Никто не запрещает, например, такое:

char s[] = "1234";
anonymous
()
Ответ на: комментарий от anonymous

Другие платформы меня не заботят :-) Вообще, никак :-)

Оно и понятно, мамкин борщ наворачивать - не рабочий код писать.

Смешной какой :-) Трюк записи в константу :-) Бугага :-)

У вас в универе лаб что-ли не было со всякими микроконтроллерами? Там и не такое бывает. Или тебе всякие быдлоуниверы не нужны?

anonymous
()
Ответ на: комментарий от anonymous

Оно и понятно, мамкин борщ наворачивать - не рабочий код писать.

А ты попробуй и борщичка навернуть мамкиного, и рабочий код пописать :-) Каждое по-своему приятно :-)

У вас в универе лаб что-ли не было со всякими микроконтроллерами?

Неа, не было :-)

Там и не такое бывает.

Не знаю, я не кодировал микроконтроллеры :-) Но я думаю, что цепепе там не впился со своими константами :-) Там рулят C, Ассемблер и Форт :-)

Или тебе всякие быдлоуниверы не нужны?

Быдлоуниверы мне не нужны :-)

anonymous
()
Ответ на: комментарий от anonymous

Но я думаю, что цепепе там не впился со своими константами :-) Там рулят C, Ассемблер и Форт :-)

Ты думаешь, а я знаю и видел. Используется только так, и для станков, и для комбайнов и т.д.

anonymous
()
Ответ на: комментарий от anonymous

Используется только так, и для станков, и для комбайнов и т.д.

И там только так можно const_cast<char*>(«zhopa») делать без проблем? :-) Буду знать этот великий и полезный трюк :-)

anonymous
()
Ответ на: комментарий от anonymous

Когда буду станок с комбайном программировать :-)

anonymous
()
Ответ на: комментарий от anonymous

И там только так можно const_cast<char*>(«zhopa») делать без проблем? :-)

Там и reinterpret_cast можно. Но это по секрету.

anonymous
()
Ответ на: комментарий от anonymous

Ладно, коллеги! :-) Время пустого трёпа вышло :-) Появилось много вкусной работы, которую нужно быстро делать, чтобы мамкин борщ не остывал по вечерам :-) Всем желаю продуктивной работы, конструктивного общения, успеха в работе и личной жизни! :-) Если что-то было сказано мной некорректно, неправильно или слишком с большим количеством смайликов, прошу простить и всерьёз не воспринимать :-) Это было всего лишь приятное времяпрепровождение :-) Всем удачи, всем успеха! :-)

anonymous
()
Ответ на: комментарий от anonymous

со всякими микроконтроллерами

Хипстота, вон из треда!

anonymous
()
Ответ на: комментарий от eao197

Царь.

А смайлик-то еще больший идиот, чем можно было себе представить:

Да нет, идиот как раз ты.

Результат:

Результат - это проблема вывода и типа строк.

typedef struct {
  char * begin, * end;
} string_t;

string_t string(char * str) { return (string_t){str, strlen(str) + str};}

string_t trim(string_t str) {
  while(*(str.begin) == ' ') ++(str.begin);
  while(*(str.end) == ' ') --(str.end);
  return str;
}

void print_string_t(string_t str) {
  write(STDOUT_FILENO, str.begin, str.end - str.begin);
  write(STDOUT_FILENO, "\n", 1);
}

int main(int argc, char *argv[]) {
  string_t test = string("       :-) :-)                   ");
  string_t trims = test;
  trims = trim(trims);
  print_string_t(test);
  print_string_t(trims);
  return 0;
}

То же самое, только без ублюдских строк. Ради тебя, авось ты реально не понимаешь что ты несёшь, а не притворяешься.

anonymous
()
Ответ на: комментарий от anonymous

warning: deprecated conversion from string constant to ‘char*’

а это для кого?

anonymous
()
Ответ на: Царь. от anonymous

strlen(str) + str
while(*(str.end) == ' ') --(str.end);

Лошара

anonymous
()
Ответ на: Царь. от anonymous

write(STDOUT_FILENO

О, царь выяснил разницу между stdin и STDIN_FILENO. На этот раз он облажался в другом %)

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

а передать «Zhopa» в f(char *) - это можно

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

anonymous
()
Ответ на: Царь. от anonymous

То же самое, только без ублюдских строк. Ради тебя, авось ты реально не понимаешь что ты несёшь, а не притворяешься.

Блин, ну как же жидко царь срется, когда берется писать код. Вуаля:

void print_string_t(string_t str) {
  write(STDOUT_FILENO, str.begin, str.end - str.begin);
  write(STDOUT_FILENO, ";", 1);
  write(STDOUT_FILENO, "\n", 1);
}
Вывод:
       :-) :-)                   ;
:-) :-)                   ;

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Блин, ну как же жидко царь срется, когда берется писать код. Вуаля:

Причем это ему еще повезло, что он не оттуда начинает обрезать, иначе str.end имел бы все шансы уйти за пределы солнечной системы левого края строки.

anonymous
()
Ответ на: комментарий от eao197

А тебе уже говорили, что ты тупой? На всякий случай напоминаю.

anonymous
()
Ответ на: комментарий от anonymous

Да это вообще офигенно удачный показатель того, что царь не умеет ни писать код, ни проверять его работоспособность. Вообще. От слова совсем.

Впрочем, человек реально больной. Как-то не хорошо получается.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

что царь не умеет ни писать код

Тебя царь уже давно помножил на ноль. Достаточно зайти в твою темку и прочитать нытьё «это для непаралельного, 400не должны рабоать нормально, большой фреймворк должен тормазить как свинья - у меня же там всё на компилтайме» и прочее. А потом прочитать посты царя и увидим, что именно царь по каждому пункту тебя обоссал и ты съехал. Ну ничего - как будет время я приду в ту темку. Я тут вчера ващебомбу нашел.

что царь не умеет ни писать код

Из чего это следует?

ни проверять его работоспособность

В целом типичная ситуация - обоссал, адепт основную тему заигнорил, ибо обделался и съехал на другую.

(str.end - 1)

anonymous
()
Ответ на: комментарий от eao197

человек реально больной

Не пытайся отмазываться. Ты не «больной». Ты тупой и чмошный. И быть таким ничтожеством - твой сознательный выбор.

anonymous
()
Ответ на: комментарий от anonymous

Причем это ему еще повезло

С чем?

что он не оттуда начинает обрезать

Откуда оттуда?

иначе str.end имел бы все шансы уйти за пределы солнечной системы левого края строки

Он уйдёт в любом случае, но это проблема не моя.

А ну и да, trim писал не я, если кто не осилил понять - я просто выкинул оттуда strlen() и днище с интом. И все его проблемы не имеют ко мне никакого отношения.

anonymous
()
Ответ на: комментарий от anonymous

Удиви меня ламерюжка.

anonymous
()
Ответ на: комментарий от anonymous

Из чего это следует?

Из детских ошибок в коде. Которые элементарно проявляются при первом же запуске «программы» с более-менее осмысленным набором проверочных данных и элементарным контролем за результатом.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Из детских ошибок в коде.

Где там детская ошибка?

Которые элементарно проявляются при первом же запуске «программы» с более-менее осмысленным набором проверочных данных и элементарным контролем за результатом.

Зачем мне это запускать? Я написал там не трим, а «строки».

anonymous
()
Ответ на: комментарий от anonymous

С чем?

С тем, что вам не подсунули строку из одних пробелов.

А ну и да, trim писал не я, если кто не осилил понять - я просто выкинул оттуда strlen() и днище с интом. И все его проблемы не имеют ко мне никакого отношения.

Эпично. Кто же наваял сей шедевр?

string_t trim(string_t str) {
  while(*(str.begin) == ' ') ++(str.begin);
  while(*(str.end) == ' ') --(str.end);
  return str;
}
Неужели смайлик? Он, конечно, идиот, но не настолько же.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

С тем, что вам не подсунули строку из одних пробелов.

Я написал тебе строки, чтобы показать, что проблема в строках, а не в триме анонима. За сам трим я ничего не говорил и ко мне он отношения не имеет.

Эпично. Кто же наваял сей шедевр?

[code=] static inline char *trim(char *s) { while (isspace(*s)) ++s; int l; if ((l = strlen(s)) > 0) { char *e = s + l - 1; while (isspace(*e)) --e; e[1] = '\0'; } return s; }

static inline char *trim(char *s) { while (isspace(*s)) ++s; while (isspace(*e)) --e; return s; }

Собственно так он и появился на свет. У него там было выне -1 - ктож знал?

anonymous
()
Ответ на: комментарий от anonymous

За сам трим я ничего не говорил и ко мне он отношения не имеет.

Вы, анонимные цари, хорошо устроились: сначала высрали говно, вас в него макнули, вы начали съезжать, мол, код не ваш.

Речь про вот этот шедевр: тыц. Этот эпически говняный trim был написан царем и не имеет никакого отношения к trim-у от смайлика. И над этим тримом здесь и стебутся.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Вы, анонимные цари, хорошо устроились: сначала высрали говно, вас в него макнули, вы начали съезжать, мол, код не ваш.

Всмысле? Ты совсем что-ли тупо? Хотя ты уже опущенный, в целом это бесполезно и обделался ты уже с изменением строки, ну ладно. Авось ты когда-то станешь человеком:

Это

string_t trim(string_t str) {
  while(*(str.begin) == ' ') ++(str.begin);
  while(*(str.end) == ' ') --(str.end);
  return str;
}

Есть это:

static inline char *trim(char *s)
{
     while (isspace(*s)) ++s;
     int l;
     if ((l = strlen(s)) > 0) {
          char *e = s + l - 1;
          while (isspace(*e)) --e;
          e[1] = '\0';
     }
     return s;
}

Которое было сокращено до:

static inline char *trim(char *s)
{
     while (isspace(*s)) ++s;
          while (isspace(*e)) --e;
     return s;
}

В котором я зыбл добавить -1, т.к. это вообще не моя проблема и не моя задача.

То, что он уезжает за строку, то что он там не работает - это не моя проблема. Моя проблема только в том, что я забыл там -1, но и то это даже не моя ошибка, а просто невнимательно скопипастил.

Этот эпически говняный trim был написан царем и не имеет никакого отношения к trim-у от смайлика.

Ога, ога. 100% написан.

И над этим тримом здесь и стебутся.

Опять же, ничтожество своё мнение считает за ноль настолько, что уже подсознательно пытается прятаться за «мы».

anonymous
()
Ответ на: комментарий от anonymous

В котором я зыбл добавить -1, т.к. это вообще не моя проблема и не моя задача.

Не считая, что «это» не «есть это», даже не считая «забыл добавить -1», есть еще и проблема с обработкой строк из одних пробелов.

ЗЫ. Вы даже не поняли, где нужно делать -1.

eao197 ★★★★★
()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от anonymous

А зачем там её прибавлять? Она там не нужна. end указывает не на конец, а за конец, т.е. на 0...10(последний символ *9), если строка из 10 символов, то 10-0 будет 10.

strlen(str) + str

Если от результата отнять str, то будет strlen(str) - не?

anonymous
()
Ответ на: комментарий от anonymous

end указывает не на конец, а за конец

после последнего --(str.end) str.end указывает на последний значимый символ - на скобочку от смайлика. Поэтому end - begin ровно на 1 меньше, чем реальная длина строки. Ты не прав.

anonymous
()
Ответ на: комментарий от eao197

есть еще и проблема с обработкой строк из одних пробелов.

Никаких проблем нет. Если там одни пробелы - оно обделается на втором цикле. Он не отработает без -1, а мой код был написан без -1.

В конечном итоге ты опять попал в вилку. Либо ты признаешь, что -1 не моя ошибка(я там уже кидал код с -1 - у тебя есть шанс съехать благодаря ему) и обедлываешься с первым уличением и тогда работает второе, но второе это уличение анонима, а если не согласен, то ты обделываешься щас.

anonymous
()
Ответ на: комментарий от anonymous

после последнего --(str.end) str.end указывает на последний значимый символ - на скобочку от смайлика. Поэтому end - begin ровно на 1 меньше, чем реальная длина строки. Ты не прав.

А какое это отношение имеют к print? Это проблема трима, опять же. Так же - он не может указывать на скобочку, ибо он не работает.

В чём конкретно я не прав?

anonymous
()
Ответ на: комментарий от anonymous

Никаких проблем нет.

Ok, вам виднее. У меня ваша программа на строке из одних пробелов падает из-за того, что str.end становится меньше str.begin. А потом вы делаете (end - begin). Отсюда и проход по памяти.

Но у вас проблем нет, все хорошо, прекрасная маркиза.

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

В чём конкретно я не прав?

В том что программа от смайлика работает, а твоя программа не работает.

anonymous
()
Ответ на: комментарий от anonymous

В том что программа от смайлика работает, а твоя программа не работает.

А еще точнее, у смайлика тоже кривой вариант, но царь сделал его еще более кривым.

anonymous
()
Ответ на: комментарий от eao197

Ok, вам виднее. У меня ваша программа на строке из одних пробелов падает из-за того, что str.end становится меньше str.begin.

Он не может стать меньше, ибо второй цикл не работает, как ты уже выяснил в первой свой попытке.

Независимо от того что там в строке - он будет указывать за строку и никогда второй цикл исполнен не будет.

А уж падать она не может никак. Даже если предположить, что оно станет(если ты добавишь туда -1 и обосрёшься с первым высером), то никак упасть внутри write() не может - по определению.

Но у вас проблем нет, все хорошо, прекрасная маркиза.

Ты просто врёшь, что я могу ещё сказать.

anonymous
()
Ответ на: комментарий от anonymous

А еще точнее, у смайлика тоже кривой вариант, но царь сделал его еще более кривым.

Чем он кривой? Работает быстрее буста, это было показано. Единственная ошибка этого смайлика в том, что он взял int вместо size_t при вызове strlen().

anonymous
()
Ответ на: комментарий от anonymous

Даже если предположить, что оно станет(если ты добавишь туда -1 и обосрёшься с первым высером), то никак упасть внутри write() не может - по определению.

Поскольку в моем распоряжении был только один кривой trim (второй есть где-то в вашей голове, но не в данном обсуждении), то пришлось ваш вариант подправить таким образом:

string_t string(char * str) { return (string_t){str, strlen(str) + str};}

string_t trim(string_t str) {
  while(*(str.begin) == ' ') ++(str.begin);
  while(*(str.end) == ' ' || !(*str.end)) --(str.end);
  return str;
}
В этом виде начинают обрезаться пробелы справа. Но т.к. у себя в trim-е вы никак не соотносите значения begin и end между собой, то уменьшение end меньше begin спокойно происходит на строке из одних пробелов. Что и вылазит затем внутри write.

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

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

Как я понял все попытки рассказать мне о том, что у меня что-то не правильно не удались? Ладно.

А с чего это она не работает? Конкретнее. Где и как она не работает? Единственная моя проблема, что я решил просто скопипастить трим, чтобы вы не ныли, что его нет. Но мне было лень и я его скопипастил криво - бывает. В целом, как я уже 10раз писал - трим ко мне никакого отношения не имеет, я не писал, не пытался и моя программа делает совершенно другое. Она выводит строки по двум указателям и создаёт строки из сишных. Остальное меня не волнует и к моей программе никакого отношения не имеет.

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

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

anonymous
()
Ответ на: комментарий от anonymous

А с чего это она не работает? Конкретнее. Где и как она не работает?

Она не тримирует строку и выдает на экран пробелы.

anonymous
()
Ответ на: комментарий от anonymous

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

Он кукарекал про то, что в память по некому адресу трим записал 0 и что исходную строку полученную в результате malloc() это не изменило. Все понятно.

anonymous
()
Ответ на: комментарий от anonymous

Работает быстрее буста, это было показано.

Не было. Кроме того на больших строках он еще и проиграет.

Единственная ошибка этого смайлика в том, что он взял int вместо size_t при вызове strlen().

Он не заметил, что менял исходную строку. Впрочем это уже можно считать придиркой.

anonymous
()
Ответ на: комментарий от anonymous

Она не тримирует строку и выдает на экран пробелы.

А он должен?

anonymous
()
Ответ на: комментарий от anonymous

Он не заметил, что менял исходную строку. Впрочем это уже можно считать придиркой.

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

anonymous
()
Ответ на: комментарий от anonymous

трим написан верно и эффективно

Только вызывать его 10M раз было бессмысленно, если после первого вызова пробелы с одного конца были уже отсечены. Или с обоих концов, не помню уже.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Только вызывать его 10M раз было бессмысленно, если после первого вызова пробелы с одного конца были уже отсечены.

Ну хз для чего. Наверное для того, чтобы замеры по time-у выполнить. Не знаю.

anonymous
()
Ответ на: комментарий от anonymous

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

Он же в этом сам признался:

Данное сравнение не честно по отношению к моему велосипеду на C, потому что мой велосипед честно триммирует строку все 10 миллионов итераций, в то время как версия на C++ триммирует строку только на 1-й итерации :-)

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

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

Наверное для того, чтобы замеры по time-у выполнить.

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

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.