Comments 71
Как теперь жить зная что меня могут оружать люди которое делают такое просто ради развлечения?
Спасибо за легкое чтиво, я теперь не усну
Compilation problems with newer or different C/C++ compilers is a common problem.
Понятно, что поддержка новый версий компилятора — большая работа, сопряжённая с риском для уже проверенного кода, и никто не будет её делать для устаревающей JDK 8, поскольку это ни разу не критичная проблема.
Кстати, ещё один хинт:
java -Xinternalversion
скажет, каким компилятором собиралась данная конкретная версия JDK. Например, для стандартного пакета в Ubuntu это будет gcc 5.4.0. Можно сэкономить кучу времени и нервов, просто выбрав для сборки gcc-5.$ java -Xinternalversion
OpenJDK 64-Bit Server VM (25.181-b13) for linux-amd64 JRE (1.8.0_181-8u181-b13-0ubuntu0.16.04.1-b13), built on Jul 30 2018 21:06:27 by "buildd" with gcc 5.4.0 20160609
И кстати, вот этот образчик еще бы обсудить
char xn[10]; sprintf(xn, "x%d", j);
- magic number,
- отсутствие проверки на размер буфера (man snprintf),
- отсутствие проверки на возвращаемый результат,
- использование неправильного формата
- и вообще использование универсальной библиотечной функции там, где должна быть специальная (itoa).
WTF. Кажется, проблема тут не с ворнингом в компиляторе, а с тем что код написан странновато.
- Переменная j (индекс аргумента) на практике всегда от 0 до 3.
- Заводить где-то отдельную константу BUFFER_SIZE для буфера, который заполняется лишь в той же строке, полагаю, перебор. Boilerplate, ничуть не улучшающий читабельность.
- И что же делать с возвращаемым значением? Проверять, что 10 байт хватит на запись трёх символов? А если нет, то что? :) По мне так тоже перебор.
- Что не так с форматом? И чем поможет
itoa
, чтобы напечататьx2
?
Я ни в коем случае не хочу оспаривать паттерны написания корректного кода, но в данном конкретном примере сразу понятно, что хотел выразить автор, и что никаких багов с переполнением буфера здесь быть не может. То, что более свежий gcc стал выдавать предупреждение — да, стоит поправить, но делать из этого выводы, что написана какая-то фигня, будет преждевременно.
Тогда вообще непонятно зачем sprintsf можно было static const char* Val's[3]{«0x0»,«0x1»,«0x2»}; завести
>Заводить где-то отдельную константу BUFFER_SIZE для буфера, который заполняется лишь в той же строке, полагаю, перебор. Boilerplate, ничуть не улучшающий читабельность.
Тем что непонятно при чем тут 10 если значения 0x1,0x2,0x3 (вроде как 4 charа), код пахнет…
>Что не так с форматом? И чем поможет itoa, чтобы напечатать x2?
Тем что любая ошибка в строке форматирования это потенциальный риск stack corruption и привет rce.(я не про данный случай а вобщем).
Поэтому в современном c++ их стараются избегать.
Поэтому лучше уж либо const char xn[10]=«x»; itoa(j,xn+1,0x10); либо стримы с std::hex
Что я понял из мира веб-программирования: код прявят ЛЮБЫЕ люди. Вполне возможно, этот человек буквально позавчера был поваром или менеджером по продажам телефонов, вчера выучил синтаксис языка и сегодня правит. Может быть это какой-то инженер, но ему очень лень разбираться, а баг надо было пофиксить ещё завтра.
Итого, самое важное, чтобы в коде без посторонних подсказок и какого-либо понимания вопроса мог разбираться даже полный клинический идиот, пуская слюни на клавиатуру. И чтобы его деятельность потом минимально повредила проекту.
Для этого нужно использовать не «паттерны написания корректного кода», а паттерны написания кода для последующего чтения и модификацией идиотами.
Например, если у тебя есть функция «умножь на два», то очевидно нужно использовать именно её, а не какую-то идиому состоящую из нескольких понятий. Это касается не только больших вещей вроде архитектуры, но и самых маленьких вещей.
Когда код не написан в таком стиле, мне становится плохо и больно. (В том числе и потому, что я сам ленивый идиот).
Не «паттерны написания корректного кода», а паттерны написания кода для последующего чтения и модификацией идиотами.
Просится в подзаголовок книги о Java ;)
и вообще использование универсальной библиотечной функции там, где должна быть специальная (itoa).
itoa() не является стандартной функцией. Так что её неиспользование вполне оправдано.
PS C:\Users\x> java -Xinternalversion
Java HotSpot(TM) 64-Bit Server VM (25.181-b13) for windows-amd64 JRE (1.8.0_181-b13), built on Jul 7 2018 04:01:33 by "java_re" with MS VC++ 10.0 (VS2010)
И в самом деле, некроманты.
Ибо, в Арче:
OpenJDK 64-Bit Server VM (25.181-b13) for linux-amd64 JRE (1.8.0_181-b13), built on Aug 10 2018 18:36:50 by «builduser» with gcc 8.2.0
build() {
cd jdk8u-${_repo_ver}
unset JAVA_HOME
# http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1346
export MAKEFLAGS=${MAKEFLAGS/-j*}
# We filter out -O flags so that the optimization of HotSpot is not lowered from O3 to O2
export CFLAGS="${CFLAGS//-O2/-O3} ${CPPFLAGS} -Wno-error=deprecated-declarations -Wno-error=stringop-overflow= -Wno-error=return-type -Wno-error=cpp -fno-lifetime-dse -fno-delete-null-pointer-checks"
export CXXFLAGS="${CXXFLAGS} ${CPPFLAGS}"
install -d -m 755 "${srcdir}/${_prefix}/"
sh configure \
--prefix="${srcdir}/${_prefix}" \
--with-update-version="${_jdk_update}" \
--with-build-number="b${_jdk_build}" \
--with-milestone="fcs" \
--enable-unlimited-crypto \
--with-zlib=system \
--with-extra-cflags="${CFLAGS}" \
--with-extra-cxxflags="${CXXFLAGS}" \
--with-extra-ldflags="${LDFLAGS}"
# TODO OpenJDK does not want last version of giflib (add 'giflib' as dependency once fixed)
#--with-giflib=system \
# These help to debug builds: LOG=trace HOTSPOT_BUILD_JOBS=1
# Without 'DEBUG_BINARIES', i686 won't build: http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-July/019203.html
make
make docs
# FIXME sadly 'DESTDIR' is not used here!
make install
cd ../${_imgdir}
# A lot of build stuff were directly taken from
# http://pkgs.fedoraproject.org/cgit/java-1.8.0-openjdk.git/tree/java-1.8.0-openjdk.spec
# http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1437
find . -iname '*.jar' -exec chmod ugo+r {} \;
chmod ugo+r lib/ct.sym
# remove redundant *diz and *debuginfo files
find . -iname '*.diz' -exec rm {} \;
find . -iname '*.debuginfo' -exec rm {} \;
}
— Насколько сейчас отличается OpenJDK и OracleJDK?
— Ваше мнение о будущем одна OracleJDK?
— Например, возможно ли объединение OpenJDK + OracleJDK?
— Если да, сообщество говорит какие-либо сроки?
— Что вы думаете о использовать JDK на CentOS vs Ubuntu?
— Когда стоит переводить тест/прод на Java 11?
Спасибо
Какой линукс используется для джавы, в целом, наплевать. Если нравится все новое — то Ubuntu, если все протухшее но стабильное — CentOS.
Переводить тест на JDK 11 нужно было вчера.
Существует проект Metropolis: Java-on-Java. Пока он не сильно продвинулся. Полагаю, потому, что все заинтересованные (типа Джона Роуза) сейчас заняты другими делами, выпуском новой LTS версии, например :)
Вот Metropolis скорей всего будет очень сильно зависеть от того, какие открытия произойдут в ходе разработки GraalVM. В частности, в OpenJDK уже интегрирован Graal Compiler из GraalVM, являющийся единственной на данный момент поддерживаемой реализацией JVMCI в виде Java-on-Java, благодаря нему же появился AOT. Некоторые совсем новые идеи и даже драфты jep (такие как в моей прошлой статье про lazy static final поля) делаются с GraalVM в уме — lazy поля нужны в SubstrateVM, ибо новая фича по оттягиванию инициализации классов до рантайма по факту работает совсем не так как хотелось бы.
Иначе говоря, имхо, GraalVM сыграет свою роль к общей картине всего, в общем историческом процессе. Но скорей всего есть и останется отдельным специализированным продуктом.
в коде не отличается от OpenJDK, кроме торговых знаков?
stackoverflow.com/questions/22358071/differences-between-oracle-jdk-and-openjdk
stackoverflow.com/questions/44335605/openjdk-vs-java-hotspotvm
Это ea, релиза же нету ещё. Релизной oracle jdk не будет бесплатно.
Так что решение собирать 5.4 вполне себе оправданно. Это к habr.com/company/jugru/blog/422861/#comment_19093509
Интересно, с CLang что то подобное наблюдается или нет
Интересно, с CLang что то подобное наблюдается или нетЭто от разработчиков больше зависит, чем от компиляторщиков. Android сейчас пользует clang 6.0.2 (притом что вышел пока только 6.0.1), но 7го пока боится…
Любой джавист в конце концов начинает писать только на C++…
Ностальгия что ли? Вот так начинаешь изучение с С++, тебя бесят указатели, вручную память выделять надо и освобождать тож, а потом берешь Java и счастье то какое — не надо всем этим заморачиваться, хотя с другой стороны получение строки с ввода выливалось в три строки кода…
у Python совершенно другая ниша. Там есть некое пересечение по Machine Learning, но оно в основном работает на нативном (C/C++) коде, на питоне там только некая лайтовая обвязка. Да, Java потеряла в направлении ML преимущество, но это всё ещё починится. В отличие от питона, числодробилки можно писать на самой Java, переходя в натив только по случаю какого-то большого горя, — и это огромное конкурентное преимущество
думаю что Java — это про высокопроизводительный безопасный код, работающий в условиях высокой конкарренси и за shared mutable state
"And I write sleek performant low-overhead scala code with higher order functions that will run on anything" © Динеш, Кремниевая долина.
Сейчас 2018-й год и баззвордами никого не удивишь. А вот индуса из стереотипов они напоминают
То есть, это системные вещи типа написания баз данных, про кластера, обработку Big Data, про Machine Learning, и так далее.
и много баз данных/ML фреймворков и обработчиков Big Data написано на джаве?
В отличие от питона, числодробилки можно писать на самой Java
А зачем, если есть питон, на котором эти числодробилки уже написаны, и под капотом у них не интерпретируемый, а нативный код на си или с++?
> баззвордами
это не баззворды, а осмысленные вещи
> и под капотом у них не интерпретируемый, а нативный код на си или с++?
2018 год на дворе, Java уже давно насквозь нативная, сейчас даже генерацию exe файлов пилят
берешь Java и счастье то какое
да тоже то еще счастье)
For an object of non-POD class type… before the constructor begins execution… referring to any non-static member or base class of the object results in undefined behavior
Чуть тупил в этом месте, поэтому хочу разжевать, вдруг ещё кому пригодится.
В нашем примере (оригинальный код не осиливал) переменная _b
является как раз static
. Также она определена после a
(форвард-объявление в классе не считается), находясь в той же самой единице трансляции (.cpp-файле). Следовательно, _b
всегда будет строиться после a
, это вполне определено, и именно поэтому у нас срабатывает оптимизация.
Более того, поскольку _b
у нас статитическая, в ней будет не мусор, а нули. Это тоже гарантировано.
Соответственно, если метод .Show()
действительно детерминированно не падает на залитом нулями объекте, то без оптимизации оно могло "стабильно" работать, пусть и неправильно.
Ну и, казалось бы, если компилятор знает, что здесь точно 100% UB, то почему он не кинет предупреждение? Поспекулирую, что основывать логику предупреждений на логике оптимизации — это общепризнанно плохая идея. Разные проходы оптимизации могут очень нетривиально взаимодействовать друг с другом, и будет получаться так, что предупреждения будут зависеть от флагов оптимизации совершенно непредсказуемым образом, что дико. Поэтому ворнинг надо реализовывать отдельно, и, видимо, ни у кого руки не дошли пока.
Любой джавист — в душе немного некромант, а может даже и некрофил.
ebanoe.it/2018/01/31/java-necromancer
</несмешно>
Сборка прошла, сгенерированы экзешники, мы молодцы.
Я надеюсь, что это метафора?
Потому что на кроссплатформенную компиляцию не похоже.
--disable-warnings-as-errors
Который делает именно это: не включает режим «предупреждения-как-ошибки».
Ну а в целом — да. Продвинутые джава-программисты в будущем станут еще и С++-программистами. Graal, Panama и всё вокруг будет приятно располагать. Нет, С++ сейчас совсем не такой страшный, каким был во времена создания Java. Это будет просто новый уровень погружения в технологию, который многие захотят пройти.
О сборке JDK 8 на Ubuntu, качестве кода Hotspot и почему всё валят на C++