PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
PVS-Studio analyzer استعمال ڪرڻ لاءِ سڀ کان وڌيڪ موجوده منظرنامن مان هڪ آهي ان جو انضمام CI سسٽم سان. ۽ جيتوڻيڪ PVS-اسٽوڊيو پروجيڪٽ جو تجزيو تقريبن ڪنهن به مسلسل انٽيگريشن سسٽم مان صرف چند حڪمن ۾ ٺاهي سگهجي ٿو، اسان انهي عمل کي اڃا به وڌيڪ آسان بڻائڻ جاري رکون ٿا. PVS-اسٽوڊيو هاڻي ٽيم سٽي - ٽيم سٽي انسپيڪشن ٽائپ لاءِ هڪ فارميٽ ۾ تجزيي جي پيداوار کي تبديل ڪرڻ جي حمايت ڪئي آهي. اچو ته ڏسو ته اهو ڪيئن ڪم ڪري ٿو.

استعمال ٿيل سافٽ ويئر بابت ڄاڻ

پي وي وي اسٽوڊيو - سي، سي ++، سي # ۽ جاوا ڪوڊ جو هڪ مستحڪم تجزيه ڪندڙ، مختلف قسمن جي غلطين کي ڳولڻ ۽ درست ڪرڻ جي ڪم کي آسان ڪرڻ لاء ٺهيل آهي. تجزيي کي ونڊوز، لينڪس ۽ macOS تي استعمال ڪري سگهجي ٿو. هن آرٽيڪل ۾ اسين فعال طور تي استعمال ڪنداسين نه رڳو تجزيه ڪندڙ پاڻ، پر ان جي ورڇ مان ڪجهه افاديت پڻ.

سي ايل مانيٽر - هڪ مانيٽرنگ سرور آهي جيڪو مانيٽر ڪري ٿو ڪمپلر لانچ. اهو توهان جي منصوبي کي تعمير ڪرڻ شروع ڪرڻ کان پهريان فوري طور تي هلائڻ گهرجي. سنوپنگ موڊ ۾، سرور سڀني سپورٽ ڪيل ڪمپلرز جي رن کي روڪيندو. اها ڳالهه نوٽ ڪرڻ جي قابل آهي ته هي افاديت صرف C/C ++ منصوبن جو تجزيو ڪرڻ لاء استعمال ڪري سگهجي ٿو.

پلگ ڪنورٽر - تجزياتي رپورٽن کي مختلف شڪلن ۾ تبديل ڪرڻ لاءِ هڪ افاديت.

مطالعي هيٺ پروجيڪٽ بابت ڄاڻ

اچو ته هن ڪارڪردگي کي عملي مثال تي آزمائي - اچو ته تجزيو ڪريون OpenRCT2 پروجيڪٽ.

اوپن آر سي ٽي 2 - راند رولر ڪوسٽر ٽائيڪون 2 (RCT2) جو کليل عمل، ان کي نئين ڪمن سان وڌائڻ ۽ بگ کي درست ڪرڻ. گیم پلے ھڪڙي تفريحي پارڪ جي تعمير ۽ برقرار رکڻ جي چوڌاري گھمندو آھي جنھن ۾ سواريون، دڪان، ۽ سهولتون شامل آھن. رانديگر کي گهرجي ته نفعو ڪمائڻ جي ڪوشش ڪري ۽ مهمانن کي خوش رکندي پارڪ جي سٺي ساک برقرار رکي. OpenRCT2 توهان کي اجازت ڏئي ٿو ته توهان ٻنهي منظرنامن ۽ سينڊ باڪس ۾ کيڏڻ جي. منظرنامو پليئر کي هڪ مقرر وقت اندر هڪ مخصوص ڪم مڪمل ڪرڻ جي ضرورت آهي، جڏهن ته سينڊ باڪس پليئر کي اجازت ڏئي ٿو وڌيڪ لچڪدار پارڪ بنا ڪنهن پابندين يا ماليات جي.

adjustment

وقت بچائڻ لاءِ، مان شايد انسٽاليشن جي عمل کي ڇڏي ڏيندس ۽ ان وقت کان شروع ڪندس جڏهن مون وٽ ٽيم سٽي سرور آهي منهنجي ڪمپيوٽر تي. اسان کي وڃڻو پوندو: localhost:{انسٽاليشن جي عمل دوران بيان ڪيل پورٽ} (منهنجي صورت ۾، localhost:9090) ۽ اختيار ڪرڻ واري ڊيٽا داخل ڪريو. داخل ٿيڻ کان پوءِ اسان کي سلام ڪيو ويندو:

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
ڪلڪ ڪريو پروجيڪٽ ٺاهيو بٽڻ. اڳيون، دستي طور تي چونڊيو ۽ فيلڊ ۾ ڀريو.

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
بٽڻ دٻائڻ کان پوء ٺاهيو، اسان کي سيٽنگن سان گڏ ونڊو طرفان سلام ڪيو ويندو.

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
اچو ته ڪلڪ ڪريو ٺاھيو ٺاھ جوڙ.

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
فيلڊ ۾ ڀريو ۽ ڪلڪ ڪريو ٺاهيو. اسان هڪ ونڊو ڏسون ٿا جيڪو توهان کي ورزن ڪنٽرول سسٽم چونڊڻ لاءِ پڇي ٿو. جيئن ته ذريعن اڳ ۾ ئي مقامي طور تي واقع آهن، ڪلڪ ڪريو ڇڏي ڏيو.

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
آخرڪار، اسان پروجيڪٽ سيٽنگون ڏانهن وڃو.

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
اچو ته اسيمبليءَ جا مرحلا شامل ڪريون، ھي ڪرڻ لاءِ ڪلڪ ڪريو: تعمير قدم -> تعمير قدم شامل ڪريو.

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
هتي اسان چونڊيو ٿا:

  • رنر جو قسم -> ڪمانڊ لائن
  • رن -> ڪسٽم اسڪرپٽ

جيئن ته اسان پروجيڪٽ جي تاليف دوران تجزيو انجام ڏينداسين، اسيمبلي ۽ تجزيو هڪ قدم هجڻ گهرجي، تنهنڪري فيلڊ ڀريو رواج اسڪرپٽ:

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
اسان بعد ۾ انفرادي قدمن تي نظر ڪنداسين. اهو ضروري آهي ته تجزيي کي لوڊ ڪرڻ، پروجيڪٽ کي گڏ ڪرڻ، ان جو تجزيو ڪرڻ، رپورٽ کي ڪڍڻ ۽ ان کي فارميٽ ڪرڻ لاء صرف ڪوڊ جون يارنهن لائينون لڳن ٿيون.

آخري شيء جيڪا اسان کي ڪرڻ جي ضرورت آهي ماحول جي متغيرن کي ترتيب ڏيو، جن کي مون انهن جي پڙهڻ جي صلاحيت کي بهتر ڪرڻ لاء ڪجهه طريقا بيان ڪيا آهن. هن کي ڪرڻ لاء، اچو ته اڳتي وڌو: پيٽرولر -> نئون پيٽرولر شامل ڪريو ۽ ٽي متغير شامل ڪريو:

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
توهان سڀني کي ڪرڻو آهي بٽڻ کي دٻايو هل مٿي ساڄي ڪنڊ ۾. جڏهن پروجيڪٽ گڏ ڪيو پيو وڃي ۽ تجزيو ڪيو پيو وڃي، مان توهان کي اسڪرپٽ بابت ٻڌائيندس.

سڌي طرح اسڪرپٽ

پهرين، اسان کي ڊائون لوڊ ڪرڻ جي ضرورت آهي جديد PVS-اسٽوڊيو تقسيم. ان لاءِ اسان استعمال ڪريون ٿا چاڪليٽ پيڪيج مينيجر. انھن لاء جيڪي ھن بابت وڌيڪ ڄاڻڻ چاھيو ٿا، ھڪڙو لاڳاپيل آھي هڪ مضمون:

choco install pvs-studio -y

اڳيون، اچو ته لانچ ڪريون CLMonitor پروجيڪٽ بلڊ ٽريڪنگ يوٽيلٽي.

%CLmon% monitor –-attach

ان کان پوء اسان منصوبي کي ماحولياتي متغير جي طور تي تعمير ڪنداسين ايم ايس بي MSBuild جي نسخي جو رستو آھي مون کي تعمير ڪرڻ جي ضرورت آھي

%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable

اچو ته PVS-اسٽوڊيو لاءِ لاگ ان ۽ لائسنس ڪيچ داخل ڪريون:

%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%

تعمير مڪمل ٿيڻ کان پوء، اڳ ۾ پروسيس ٿيل فائلون ۽ جامد تجزيو پيدا ڪرڻ لاء ٻيهر CLMonitor کي هلائڻ:

%CLmon% analyze -l "c:ptest.plog"

ان کان پوء اسان اسان جي تقسيم مان هڪ ٻيو استعمال ڪنداسين. PlogConverter ھڪڙي رپورٽ کي ھڪڙي معياري شڪل مان ھڪڙي ٽيم سٽي-مخصوص فارميٽ ۾ تبديل ڪري ٿو. انهي جي مهرباني، اسان ان کي سڌو سنئون تعمير ونڊو ۾ ڏسي سگهنداسين.

%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"

آخري قدم ۾ فارميٽ ٿيل رپورٽ ڊسپلي ڪرڻ آهي اسٽوريج، جتي ان کي ورتو ويندو ٽيم سٽي پارسر طرفان.

type "C:tempptest.plog_TeamCity.txt"

مڪمل اسڪرپٽ ڪوڊ:

choco install pvs-studio -y
%CLmon% monitor --attach
set platform=x64
%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable
%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%
%CLmon% analyze -l "c:ptest.plog"
%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"
type "C:tempptest.plog_TeamCity.txt"

ساڳئي وقت ۾، منصوبي جي اسيمبلي ۽ تجزيو ڪاميابي سان مڪمل ڪيو ويو آهي، اسان ٽيب ڏانهن وڃو پروجيڪٽ ۽ پڪ ڪريو.

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
هاڻي اچو ته ڪلڪ ڪريو مجموعي چڪاسanalyzer رپورٽ ڏسڻ لاءِ:

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
ڊيڄاريندڙن کي تشخيصي ضابطن جي انگن اکرن سان گڏ ڪيو ويو آهي. ڪوڊ ذريعي نيويگيٽ ڪرڻ لاء، توهان کي ڊيڄاريندڙ سان لائن نمبر تي ڪلڪ ڪرڻ جي ضرورت آهي. مٿي ساڄي ڪنڊ ۾ سوال جي نشان تي ڪلڪ ڪندي توهان کي دستاويزن سان گڏ هڪ نئون ٽيب کوليندو. توھان پڻ ڪري سگھوٿا ڪوڊ ذريعي نيويگيٽ ڪري سگھوٿا لائن نمبر تي ڪلڪ ڪري تجزيي وارن وارننگ سان. ريموٽ ڪمپيوٽر کان نيويگيشن ممڪن آهي جڏهن استعمال ڪندي SourceTreeRoot مارڪر ڪو به ماڻهو جيڪو تجزيي جي آپريشن جي هن موڊ ۾ دلچسپي رکي ٿو پاڻ کي لاڳاپيل سيڪشن سان واقف ڪري سگهي ٿو دستاويز.

تجزيي جي نتيجن کي ڏسڻ

ھاڻي ته اسان ٺاھڻ ۽ ٺاھڻ جو ڪم ڪيو آھي، اچو ته ھڪڙي نظر رکون ڪجھ دلچسپ ڊيڄاريندڙن تي مليا آھن پروجيڪٽ ۾ جيڪي اسان ڏسي رھيا آھيون.

خبردار N1

V773 [CWE-401] استثنا 'نتيجو' پوائنٽر جاري ڪرڻ کان سواءِ اڇلايو ويو. هڪ ميموري ليڪ ممڪن آهي. libopenrct2 ObjectFactory.cpp 443

Object* CreateObjectFromJson(....)
{
  Object* result = nullptr;
  ....
  result = CreateObject(entry);
  ....
  if (readContext.WasError())
  {
    throw std::runtime_error("Object has errors");
  }
  ....
}

Object* CreateObject(const rct_object_entry& entry)
{
  Object* result;
  switch (entry.GetType())
  {
    case OBJECT_TYPE_RIDE:
      result = new RideObject(entry);
      break;
    case OBJECT_TYPE_SMALL_SCENERY:
      result = new SmallSceneryObject(entry);
      break;
    case OBJECT_TYPE_LARGE_SCENERY:
      result = new LargeSceneryObject(entry);
      break;
    ....
    default:
      throw std::runtime_error("Invalid object type");
  }
  return result;
}

تجزيه نگار هڪ غلطي محسوس ڪئي جيڪا متحرڪ طور تي ميموري کي مختص ڪرڻ کان پوءِ CreateObject، جڏهن هڪ استثنا ٿئي ٿي، ياداشت صاف نه ڪئي وئي آهي، ۽ هڪ ميموري ليک ٿئي ٿي.

خبردار N2

V501 هڪجهڙا ذيلي اظهار آهن '(1ULL << WIDX_MONTH_BOX)' کاٻي ۽ ساڄي طرف '|' آپريٽر libopenrct2ui Cheats.cpp 487

static uint64_t window_cheats_page_enabled_widgets[] = 
{
  MAIN_CHEAT_ENABLED_WIDGETS |
  (1ULL << WIDX_NO_MONEY) |
  (1ULL << WIDX_ADD_SET_MONEY_GROUP) |
  (1ULL << WIDX_MONEY_SPINNER) |
  (1ULL << WIDX_MONEY_SPINNER_INCREMENT) |
  (1ULL << WIDX_MONEY_SPINNER_DECREMENT) |
  (1ULL << WIDX_ADD_MONEY) |
  (1ULL << WIDX_SET_MONEY) |
  (1ULL << WIDX_CLEAR_LOAN) |
  (1ULL << WIDX_DATE_SET) |
  (1ULL << WIDX_MONTH_BOX) |  // <=
  (1ULL << WIDX_MONTH_UP) |
  (1ULL << WIDX_MONTH_DOWN) |
  (1ULL << WIDX_YEAR_BOX) |
  (1ULL << WIDX_YEAR_UP) |
  (1ULL << WIDX_YEAR_DOWN) |
  (1ULL << WIDX_DAY_BOX) |
  (1ULL << WIDX_DAY_UP) |
  (1ULL << WIDX_DAY_DOWN) |
  (1ULL << WIDX_MONTH_BOX) |  // <=
  (1ULL << WIDX_DATE_GROUP) |
  (1ULL << WIDX_DATE_RESET),
  ....
};

هڪ جامد تجزيه نگار کان سواءِ ڪجهه ماڻهو هن اطمينان جو امتحان پاس ڪري سگھن ٿا. هي ڪاپي پيسٽ مثال هن سبب لاء سٺو آهي.

ڊيڄاريندڙ N3

V703 اهو عجيب آهي ته نڪتل طبقي ۾ 'پرچم' فيلڊ 'RCT12BannerElement' بيس ڪلاس 'RCT12TileElementBase' ۾ فيلڊ مٿان لکندو آهي. لائنون چيڪ ڪريو: RCT12.h:570, RCT12.h:259. libopenrct2 RCT12.h 570

struct RCT12SpriteBase
{
  ....
  uint8_t flags;
  ....
};
struct rct1_peep : RCT12SpriteBase
{
  ....
  uint8_t flags;
  ....
};

يقينن، بنيادي طبقي ۽ اولاد ۾ ساڳئي نالي سان متغير استعمال ڪرڻ هميشه غلطي ناهي. بهرحال، وراثت ٽيڪنالاجي پاڻ کي فرض ڪري ٿو ته والدين طبقي جا سڀئي شعبا ٻار جي طبقي ۾ موجود آهن. ورثي ۾ ساڳئي نالي سان شعرن کي بيان ڪندي، اسان مونجهارو متعارف ڪرايو.

خبردار N4

V793 اهو عجيب آهي ته 'imageDirection / 8' بيان جو نتيجو شرط جو حصو آهي. شايد، هن بيان کي ڪنهن ٻئي سان ڀيٽيو وڃي ها. libopenrct2 ObservationTower.cpp 38

void vehicle_visual_observation_tower(...., int32_t imageDirection, ....)
{
  if ((imageDirection / 8) && (imageDirection / 8) != 3)
  {
    ....
  }
  ....
}

اچو ته هڪ ويجهي نظر وٺو. اظهار تصوير جي هدايت/8 غلط ٿيندو جيڪڏهن تصوير جي هدايت -7 کان 7 تائين جي حد ۾ آهي. ٻيو حصو: (تصوير جي هدايت / 8) != 3 چيڪ تصوير جي هدايت حد کان ٻاهر هجڻ لاءِ: -31 کان -24 تائين ۽ 24 کان 31 تائين. اهو مون لاءِ ڪافي عجيب لڳي ٿو انگن کي چيڪ ڪرڻ لاءِ هڪ خاص حد ۾ شامل ڪرڻ لاءِ هن طريقي سان ۽، جيتوڻيڪ ڪوڊ جي هن ٽڪڙي ۾ ڪا به غلطي نه آهي، مان انهن شرطن کي ٻيهر لکڻ جي صلاح ڏيندس وڌيڪ واضح ٿيڻ لاءِ. اهو انهن ماڻهن لاءِ زندگي تمام گهڻو آسان بڻائيندو جيڪي هن ڪوڊ کي پڙهندا ۽ برقرار رکندا.

خبردار N5

V587 هن قسم جي تفويض جو هڪ عجيب سلسلو: A = B؛ ب = ا؛. لائنون چيڪ ڪريو: 1115, 1118. libopenrct2ui MouseInput.cpp 1118

void process_mouse_over(....)
{
  ....
  switch (window->widgets[widgetId].type)
  {
    case WWT_VIEWPORT:
      ebx = 0;
      edi = cursorId;                                 // <=
      // Window event WE_UNKNOWN_0E was called here,
      // but no windows actually implemented a handler and
      // it's not known what it was for
      cursorId = edi;                                 // <=
      if ((ebx & 0xFF) != 0)
      {
        set_cursor(cursorId);
        return;
      }
      break;
      ....
  }
  ....
}

هي ڪوڊ ٽڪرا گهڻو ڪري ڊمپپليشن ذريعي حاصل ڪيو ويو. ان کان پوء، فيصلو ڪندي تبصرو ڇڏي، غير ڪم ڪندڙ ڪوڊ جو حصو هٽايو ويو. تنهن هوندي، اڃا تائين ڪجھ آپريشن باقي آهن cursorId، جنهن جو پڻ گهڻو مطلب ناهي.

خبردار N6

V1004 [CWE-476] 'پليئر' پوائنٽر غير محفوظ طور تي استعمال ڪيو ويو ان جي تصديق ٿيڻ کان پوءِ nullptr جي خلاف. لائنون چيڪ ڪريو: 2085، 2094. libopenrct2 Network.cpp 2094

void Network::ProcessPlayerList()
{
  ....
  auto* player = GetPlayerByID(pendingPlayer.Id);
  if (player == nullptr)
  {
    // Add new player.
    player = AddPlayer("", "");
    if (player)                                          // <=
    {
      *player = pendingPlayer;
       if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER)
       {
         _serverConnection->Player = player;
       }
    }
    newPlayers.push_back(player->Id);                    // <=
  }
  ....
}

هي ڪوڊ درست ڪرڻ بلڪل آسان آهي؛ توهان کي صرف ان کي ٽيون ڀيرو چيڪ ڪرڻ جي ضرورت آهي رانديگر هڪ null پوائنٽر ڏانهن، يا ان کي مشروط بيان جي جسم ۾ شامل ڪريو. مان ٻيو اختيار ڏيندس:

void Network::ProcessPlayerList()
{
  ....
  auto* player = GetPlayerByID(pendingPlayer.Id);
  if (player == nullptr)
  {
    // Add new player.
    player = AddPlayer("", "");
    if (player)
    {
      *player = pendingPlayer;
      if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER)
      {
        _serverConnection->Player = player;
      }
      newPlayers.push_back(player->Id);
    }
  }
  ....
}

خبردار N7

V547 [CWE-570] اظهار 'نالو == nullptr' هميشه غلط آهي. libopenrct2 ServerList.cpp 102

std::optional<ServerListEntry> ServerListEntry::FromJson(...)
{
  auto name = json_object_get(server, "name");
  .....
  if (name == nullptr || version == nullptr)
  {
    ....
  }
  else
  {
    ....
    entry.name = (name == nullptr ? "" : json_string_value(name));
    ....
  }
  ....
}

توھان حاصل ڪري سگھوٿا سخت-پڙھڻ واري ڪوڊ جي لائن ھڪڙي ھڪڙي جھلي ۾ ۽ مسئلو حل ڪرڻ سان nullptr. مان ھيٺ ڏنل ڪوڊ کي تبديل ڪرڻ جي صلاح ڏيان ٿو:

std::optional<ServerListEntry> ServerListEntry::FromJson(...)
{
  auto name = json_object_get(server, "name");
  .....
  if (name == nullptr || version == nullptr)
  {
    name = ""
    ....
  }
  else
  {
    ....
    entry.name = json_string_value(name);
    ....
  }
  ....
}

خبردار N8

V1048 [CWE-1164] The 'ColumnHeaderPressedCurrentState' متغير ساڳئي قدر مقرر ڪيو ويو. libopenrct2ui CustomListView.cpp 510

void CustomListView::MouseUp(....)
{
  ....
  if (!ColumnHeaderPressedCurrentState)
  {
    ColumnHeaderPressed = std::nullopt;
    ColumnHeaderPressedCurrentState = false;
    Invalidate();
  }
}

ڪوڊ بلڪل عجيب لڳي ٿو. اهو مون کي لڳي ٿو ته اتي هڪ ٽائپو هو يا ته حالت ۾ يا جڏهن متغير کي ٻيهر تفويض ڪيو ويو ڪالم هيڊر پريس ٿيل ڪرنٽ اسٽيٽ مطلب ڪوڙي.

ٿڪل

جئين اسان ڏسي سگهون ٿا، PVS-Studio جامد تجزيه ڪندڙ کي توهان جي ٽيم سٽي پروجيڪٽ ۾ ضم ڪرڻ بلڪل سادو آهي. هن کي ڪرڻ لاء، اهو ڪافي آهي صرف هڪ ننڍڙي ترتيب واري فائيل لکڻ لاء. ڪوڊ چيڪ ڪرڻ توهان کي اسيمبلي کان فوري طور تي مسئلن جي نشاندهي ڪرڻ جي اجازت ڏيندو، جيڪا انهن کي ختم ڪرڻ ۾ مدد ڪندي جڏهن تبديلين جي پيچيدگي ۽ قيمت اڃا به گهٽ آهي.

PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو
جيڪڏهن توهان هن مضمون کي انگريزي ڳالهائيندڙ سامعين سان حصيداري ڪرڻ چاهيو ٿا، مهرباني ڪري ترجمو لنڪ استعمال ڪريو: Vladislav Stolyarov. PVS-اسٽوڊيو ۽ مسلسل انضمام: ٽيم سٽي. اوپن رولر ڪوسٽر ٽائيڪون 2 پروجيڪٽ جو تجزيو.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو