реклама на сайте
подробности

 
 
19 страниц V  « < 2 3 4 5 6 > »   
Reply to this topicStart new topic
> Си
ReAl
сообщение Jan 25 2013, 12:48
Сообщение #46


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Буратино @ Jan 25 2013, 13:11) *
с исключающим или мне не очень, хотя красиво конечно a ^= b ^= a ^= b;
UB на двух записях в a в переделах sequence point. Правильно так, как было написано сначала, в три строки. Можно записать в две, но это уже неинтересно.

Цитата(Буратино @ Jan 25 2013, 13:11) *
Код
       *beg += *end - (*end = *beg);
Вам так хочется UB-иться?
UB на произвольном порядке вычисления подвыражений (тут возможность записи в *end в скобках в правом аргументе операции вычитания до того, как будет прочитано *end в левом операнде).


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 25 2013, 12:54
Сообщение #47


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Что еще за UB? Мы ж так не UBьемся!
Последовательность операций в a ^= b ^= a ^= b; определена точно. Справа налево.
Go to the top of the page
 
+Quote Post
Буратино
сообщение Jan 25 2013, 12:58
Сообщение #48


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215



что такое UB? что такое в пределах sequence point?
a ^= b ^= a ^= b;
сначала выполнится a ^= b ,затем b ^= a и в конце a ^= b по идее все верно. Нужно проверить.


Код
*beg += *end - (*end = *beg);

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


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 25 2013, 13:20
Сообщение #49


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Да вроде всегда была определена последовательность вычислений, но не последовательность записи результатов.
Так как значением выражения (a = B) является не «содержимое а после записи», а «значение b приведенное к неквалифицированному типу а».
А (a ^= B) это «то же, что и (a = a ^ B), за исключением того, что a оценивается один раз»
А порядок записи в пределах между точками следования неопределён.

Но что-то меня LWS поколебал...

http://liveworkspace.org/code/Ll7BX$13

gcc по 4.6.3 выдаёт
Цитата
source.cpp:7:20: warning: operation on 'a' may be undefined [-Wsequence-point]

в режимах и C, и C++, gcc 4.7.2 только в режиме C, но не в C++

clang 3.2 доволен всем.

Для меня это новость. Первое (и последнее -- больше так не баловался) предупреждение на a ^= b ^= a ^= b; я получил как бы не от BCC5 уже не помню как давно. Почитал стандарт. Вроде понял :-)

Что касается *beg += *end - (*end = *beg);, то все компиляторы единодушны -- UB (undefined behavior).


Цитата(Буратино @ Jan 25 2013, 14:58) *
что такое UB? что такое в пределах sequence point?
«тут мне кажется», что Вы рано за такие оптимизации взялись :-)

Sequence_point популярно для начала.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 25 2013, 13:23
Сообщение #50


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Гнаться за мнимым весом строки - позор sm.gif
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 25 2013, 13:43
Сообщение #51


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Хех.
Цитата(С99)
6.5.16 Assignment operators
Syntax
assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
assignment-operator: one of
= *= /= %= += -= <<= >>= &= ^= |=
...

Semantics
3 An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue. The type of an assignment expression is the type of the left operand unless the left operand has qualified type, in which case it is the unqualified version of the type of the left operand. The side effect of updating the stored value of the left operand shall occur between the previous and the next sequence point.


Цитата(C++11)
5.17 Assignment and compound assignment operators
...
In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.
Это они сводят поведение assignment operators для POD к поведению перегруженных операторов для классов (которые есть функции и уж точно завершат запись до возврата значения)?

Свежий стандарт C (не С++) у кого-то есть? Недавно и C обновили, не только С++


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 25 2013, 14:07
Сообщение #52


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Наверное, цитата по ссылке
At the end of a full expression. This category includes expression statements (such as the assignment a=b;)
говорит, что любое ^= создает sequence point.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 25 2013, 16:10
Сообщение #53


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Не говорит. В "например" определяющей является точка с запятой, заканчивающая утверждение, а не присваивающий оператор, являющийся вместе со своими операндами выражением.
Цитата
6.8 Statements and blocks
Syntax
1
statement:
labeled-statement
compound-statement
expression-statement
selection-statement
iteration-statement
jump-statement

4 A full expression is an expression that is not part of another expression or of a declarator.
Each of the following is a full expression: an initializer; the expression in an expression
statement;
the controlling expression of a selection statement (if or switch); the
controlling expression of a while or do statement; each of the (optional) expressions of
a for statement; the (optional) expression in a return statement. The end of a full
expression is a sequence point.

6.8.3 Expression and null statements
Syntax
expression-statement:
expressionopt ;
Т.е. expression в данному случае превращается в full expression путём участия в expression statement при помощи завершения символом
;
т.е.:
a = b = c = d; Это один expression-statement, превращает в full-expression всё a = b = c = d
Cостоящее из нескольких subexpression.

Может, в С++, особенно в C++11, что-то и не так, я туда ещё так не вчитывался.
Какие-то моменты, undefined в C, стали unspecified в C++, с этими их тонкостями ещё пойди разберись.

Да, кстати, я не подчеркнул отдельно
Цитата( @ Jan 25 2013, 13:11) *
как можно простенькие такие программки потестить?

Вот ответ, разными компиляторами можно:

http://liveworkspace.org

Причём не только C/C++.
В ответ на кусок кода вся диагностическая выдача компилятора (в зависимости от ключей) и, при создании исполняемого файла, выдача на stdout


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Буратино
сообщение Jan 28 2013, 14:11
Сообщение #54


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215



Вот еще вариант. В основе смелая идея (уже ранее высказанная) о том чтоб испоьзовать буфер, но я немного переосмыслил это дело sm.gif

Код
#include <stdio.h>
#define MAX_LEN 100

char * reverse ( char *s ) {
   static char buf[MAX_LEN];
   char *buf_pointer = &buf[MAX_LEN-1];

   while ( (*buf_pointer-- = *s++) )  // компилятор попросил о 2х скобках, ну раз ему так легче, то пусть будут:)
;
   return buf_pointer+2;
}

int main() {
   char s[]= "Hello World!";
   printf("%s\n", reverse (s) );

}


Код
stdout:
!dlroW olleH


Итак, я считаю что с задачей А мы справились. Плавно переходим к задаче Б..

Задача Б
В этой реализации мне не нравится, что в случае дефолта сначала проверится один кейс, затем другой и только потом собственно выполнится подходящее действие! Что если нужно например месяца из чисел в названия переводить или там справочные данные какие?
Потом мне непонятно почему нужно static const char strue[]="бла-бла-бла"; делать!? Это в смысле что строки в памяти программ расположатся? Как с доступом к таким значениям? не будет страдать производительность?

Код
static const char strue[]="TRUE";
static const char sfalse[]="FALSE";
static const char sndef[]="OUT OF RANGE";
switch(boolean)
{
  case true:
   return &strue;
  case false:
   return &sfalse;
  default:
   return &sndef;
}


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
xemul
сообщение Jan 28 2013, 14:46
Сообщение #55



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(Буратино @ Jan 28 2013, 18:11) *
Итак, я считаю что с задачей А мы справились.

Для таких программ потом и пишут заплатки на тему переполнения какого-нить буфера.
Цитата
Потом мне непонятна почему нужно static const char strue[]="бла-бла-бла"; делать!?

static - чтобы можно было вернуть из функции указатель на что-то вменяемое, const - считайте просто правилом хорошего тона.
Go to the top of the page
 
+Quote Post
Буратино
сообщение Jan 28 2013, 14:52
Сообщение #56


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215



Цитата(xemul @ Jan 28 2013, 18:46) *
Для таких программ потом и пишут заплатки на тему переполнения какого-нить буфера.

static - чтобы можно было вернуть из функции указатель на что-то вменяемое, const - считайте просто правилом хорошего тона.


Для этой задачи оптимальным наверное будет сочетание двух подходов: в случае если длина строки не более чем MAX_LEN использовать один подход, если больше - второй, и менять данные прямо по месту. Я пока еще не придумал как красиво пофиксить переполнение буфера ибо нужно на каждой итерации проверять условие достижения конца буфера, а мне не оч. такой вариант.


Вот у меня тоже static, но при этом данные в массиве указателей описаны внутри функции, вроде так логичнее получается ,зачем выносить их наружу меняя область действия?
Код
char *b2s (char b) {
   static char *name[] = {"Out Of Range", "False", "True"};
   return (b < 0 || b > 1) ? name[0] : name [b+1];
}


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 28 2013, 15:04
Сообщение #57


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Буратино @ Jan 28 2013, 16:11) *
Итак, я считаю что с задачей А мы справились.
Поосторожнее… А то сейчас набегут спецы, которые сначала скажут, что возвращать указатель на внутренний статический буфер нельзя, потом скажут, что они имели ввиду, что оно-то можно, но глюкодром. А на вопрос, чем именно
Код
const char *foo()
{
    static char buf[10];
    ...
    return buf;
}
глюкодромее
Код
const char *moo()
{
    return "bla-bla-bla";
}
просто не будут отвечать по существу.
Недостаток у способа один:
Код
char str1[] = "String 1";
char str2[] = "String 2";
printf("%s %s\n", reverse(str1), reverse(str2));
Впрочем, для таких случаев мои функции подобного типа принимают второй аргумент (со значением по умолчанию в C++), которым программа, имеющая желание в одни заход получить несколько строк, обязан апередать буфер достаточного размера:
Код
const char *reverse(const char *src, char *tmpbuf = 0)
{
    static char inernal_buf[сикоку_не_жаль];
    if (!tmpbuf) tmpbuf = internal_buf;
    …
    return tmpbuf; // или что там надо по алгоритму
}
В итоге в большинстве случаев вызывается reverse(some_string); (второй аргумент по умолчанию подставляется 0), и только в отдельных случаях подставляется доп. буфер.

Однако задача в некотором смысле не решена и не может быть решена без уточнения условий и целей.
Например, если цель — скорость, а строки преимущественно «достаточно длинные», а процессор Cortex-M3 или другой, имеющий команду реверся байтов в 32-битном слове (i486+), то стоит подумать о зачитывании по 32 бита, реверсе порядка байтов соответствующей командой и т.п. Соответственно, с выделением места под буфер кратно 4 байтам + под концевой 0, спецобработкой хвоста из 1..3 символов и возвратом указателя на tmp_buf с нужным смещением.
«Если Вы не указали цель оптимизации, то Вам всё равно, как писать код» © Чеширсикй Кот – программист.

Цитата(Буратино @ Jan 28 2013, 16:11) *
Это в смысле что строки в памяти программ расположатся? Как с доступом к таким значениям? не будет страдать производительность?
По простому const объекты расположатся в памяти программ только у тех процессоров, у которых память программ и память данных находятся в одном и том же адресном пространстве.
(чтобы не повторяться)

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


Цитата(xemul @ Jan 28 2013, 16:46) *
Для таких программ потом и пишут заплатки на тему переполнения какого-нить буфера.
Я надеюсь, высказывание касается только того, что перед реверсом либо в процессе оного не проверияется длина строки. Само по себе наличие промежуточного буфера фиксированного размера к ошибкам переполнения буфера не приводит.



Цитата(Буратино @ Jan 28 2013, 16:52) *
Вот у меня тоже static, но при этом данные в массиве указателей описаны внутри функции, вроде так логичнее получается ,зачем выносить их наружу меняя область действия?
Код
char *b2s (char b) {
   static char *name[] = {"Out Of Range", "False", "True"};
   return (b < 0 || b > 1) ? name[0] : name [b+1];
}
Да, лучше внутри функции.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
xemul
сообщение Jan 28 2013, 16:10
Сообщение #58



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(ReAl @ Jan 28 2013, 19:04) *
Я надеюсь, высказывание касается только того, что перед реверсом либо в процессе оного не проверияется длина строки.

Безусловно.
Т.к. в условии задачи не сказано, что исходная строка должна сохраниться, я бы делал реверс на месте. Цена вопроса - один strlen(). (оно, конечно, не спасёт, если строка вдруг окажется без '\0')
Цитата
Само по себе наличие промежуточного буфера фиксированного размера к ошибкам переполнения буфера не приводит.

К переполнению, естественно, не приведёт. Но если память (опять же вдруг) закончится...

За жисть. У меня K&R был первого советского издания (в мягком переплёте, голубая обложка), не помню в нём таких упражнений. Хотя, может опять склероз буйствует.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 28 2013, 18:45
Сообщение #59


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(xemul @ Jan 28 2013, 18:10) *
Т.к. в условии задачи не сказано, что исходная строка должна сохраниться, я бы делал реверс на месте. Цена вопроса - один strlen(). (оно, конечно, не спасёт, если строка вдруг окажется без '\0')
Так в том-то и дело, что в условии задачи не сказано ничего (см. выше про Чеширского Кота – программиста). Как я говорил дочери, когда в школе на информатике пошёл паскаль, — программу можно оптимизировать на скорость написания, на простоту отладки, на скорость выполнения, на минимальный размер, на скорость понимания другим человеком, …
«Множество чего? Просто множество!» (что-то меня на Алису потянуло) «просто оптимизировать» невозможно.

Цитата(xemul @ Jan 28 2013, 18:10) *
За жисть. У меня K&R был первого советского издания (в мягком переплёте, голубая обложка), не помню в нём таких упражнений. Хотя, может опять склероз буйствует.
У меня был K&R, любовно кем-то подготовленный (фигурные скобки сделаны из круглых с надпечаткой поверх минусом, ключевые слова двойной печатью, …) и напечатанный на барабанном АЦПУ, переплетённый в переплётной мастерской (кажись, в один заказ с дипломной работй жены, тогда это 1987 год). Тоже таких упражнений не помню :-)


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 29 2013, 08:24
Сообщение #60


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(xemul @ Jan 28 2013, 19:10) *
У меня K&R был первого советского издания (в мягком переплёте, голубая обложка), не помню в нём таких упражнений. Хотя, может опять склероз буйствует.

Во втором издании (в мягком переплете, белая обложка, голубая буква С) есть упражнения по переворачиванию строки.
Go to the top of the page
 
+Quote Post

19 страниц V  « < 2 3 4 5 6 > » 
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 20:02
Рейтинг@Mail.ru


Страница сгенерированна за 0.01516 секунд с 7
ELECTRONIX ©2004-2016